When connection get back I want to run this task, I want to call NewortchangeReceiver() constructor. I wrote "android.net.conn.CONNECTIVITY_CHANGE" in Mainactivity IntentFilter because "android.net.conn.CONNECTIVITY_CHANGE" not work in androidmanifest.xml in android N (7). I want to automatic reload webview at internet connection change.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
wvDailyDarshan = (WebView) findViewById(R.id.wvDailyDarshan);
progressBar = (ProgressBar) findViewById(R.id.progressBar);
IntentFilter intentFilter = new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE");
context.registerReceiver(new NetworkChangeReceiver(), intentFilter);
Boolean connection = isNetworkConnected();
if (connection == false) {
Snackbar.make(this.getWindow().getDecorView().findViewById(android.R.id.content), "Please check your Internet Connection", Snackbar.LENGTH_SHORT).show();
} else if (connection == true) {
wvDailyDarshan.getSettings().setJavaScriptEnabled(true);
//wvDailyDarshan.loadUrl("http://www.swaminarayanbhagwan.com/daily-darshan/");
wvDailyDarshan.setWebViewClient(new myWebClient());
wvDailyDarshan.getSettings().setJavaScriptEnabled(true);
wvDailyDarshan.getSettings().setBuiltInZoomControls(true);
wvDailyDarshan.getSettings().setDisplayZoomControls(false);
wvDailyDarshan.loadUrl("https://www.google.co.in/");
}
}
What I get from your question is that you want to get callback when there is change in connectivity.
So I'll answer for that.
NetworkChangeReceiver:
public class NetworkChangeReceiver extends BroadcastReceiver {
ConnectionChangeCallback connectionChangeCallback;
#Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager cm = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
boolean isConnected = activeNetwork != null
&& activeNetwork.isConnectedOrConnecting();
if (connectionChangeCallback != null) {
connectionChangeCallback.onConnectionChange(isConnected);
}
}
public void setConnectionChangeCallback(ConnectionChangeCallback
connectionChangeCallback) {
this.connectionChangeCallback = connectionChangeCallback;
}
public interface ConnectionChangeCallback {
void onConnectionChange(boolean isConnected);
}
}
Now your Activity should call setConnectionChangeCallback on BraodCastReceiver ie NetworkChangeReceiver's object and provide ConnectionChangeCallback's implementation.
Which may look like this.
Activity:
public class YourActivity implments NetworkChangeReceiver.ConnectionChangeCallback
{
#Override
protected void onCreate(Bundle savedInstanceState) {
.....
IntentFilter intentFilter = new
IntentFilter("android.net.conn.CONNECTIVITY_CHANGE");
NetworkChangeReceiver networkChangeReceiver = new NetworkChangeReceiver();
registerReceiver(networkChangeReceiver, intentFilter);
networkChangeReceiver.setConnectionChangeCallback(this);
}
#Override
public void onConnectionChange(boolean isConnected) {
if(isConnected){
// will be called when internet is back
}
else{
// will be called when internet is gone.
}
}
}
You can create a new method, which will call itself if internet is not connected. A rough example is below. Change it to more efficient way.
private boolean shoudShowSnackbar = true;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
wvDailyDarshan = (WebView) findViewById(R.id.wvDailyDarshan);
progressBar = (ProgressBar) findViewById(R.id.progressBar);
IntentFilter intentFilter = new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE");
context.registerReceiver(new NetworkChangeReceiver(), intentFilter);
doThisThingIfFoundInternet();
}
private void doThisThingIfFoundInternet() {
if (isNetworkConnected()) {
wvDailyDarshan.getSettings().setJavaScriptEnabled(true);
//wvDailyDarshan.loadUrl("http://www.swaminarayanbhagwan.com/daily-darshan/");
wvDailyDarshan.setWebViewClient(new myWebClient());
wvDailyDarshan.getSettings().setJavaScriptEnabled(true);
wvDailyDarshan.getSettings().setBuiltInZoomControls(true);
wvDailyDarshan.getSettings().setDisplayZoomControls(false);
wvDailyDarshan.loadUrl("https://www.google.co.in/");
}else{
if (this.shoudShowSnackbar) {
Snackbar.make(this.getWindow().getDecorView().findViewById(android.R.id.content), "Please check your Internet Connection", Snackbar.LENGTH_SHORT).show();
shoudShowSnackbar = !shoudShowSnackbar;
}
doThisThingIfFoundInternet();
}
}
Related
I have a problem with the service BLE to socket connection. When trying to connect, he receives the error:
I/System.out: Status: connection failed: Attempt to invoke virtual
method 'void
com.bart111.project.bluetooth.SerialService.connect(com.bart111.project.bluetooth.SerialSocket)'
on a null object reference
Where do I go wrong?
public class MainActivity extends BaseActivity implements View.OnClickListener, ServiceConnection, SerialListener {
private List<Fragment> fragments = new ArrayList<>();
private MapsFragment mapsFragment;
private TabBarView myTabbar;
private enum Connected { False, Pending, True }
private String deviceAddress;
private SerialService service;
private Connected connected = Connected.False;
private boolean initialStart = true;
private boolean hexEnabled = false;
#Override
public void onServiceConnected(ComponentName name, IBinder binder) {
service = ((SerialService.SerialBinder) binder).getService();
service.attach(this);
if(initialStart) {
initialStart = false;
runOnUiThread((this::connect));
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
// Read BLE device.
SharedPreferences pref = getApplicationContext().getSharedPreferences("BLEPreferences", 0);
String BLEDevice = (pref.getString("device", ""));
if (BLEDevice.equals(""))
startActivity(new Intent(this, BluetoothActivity.class));
else
deviceAddress = BLEDevice;
}
#Override
protected void onStart() {
super.onStart();
if(service != null) {
service.attach(this);
} else {
bindService(new Intent(this, SerialService.class), this, Context.BIND_AUTO_CREATE);
startService(new Intent(this, SerialService.class));
connect();
}
}
private void connect() {
try {
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
BluetoothDevice device = bluetoothAdapter.getRemoteDevice(deviceAddress);
status("connecting...");
connected = Connected.Pending;
SerialSocket socket = new SerialSocket(getApplicationContext(), device);
service.connect(socket);
} catch (Exception e) {
onSerialConnectError(e);
}
}
You have declared serialService but have not assigned a value to it, hence the null object reference. You should assign initialize the serialService object before trying to invoke it.
I'm trying to disconnect from WiFi network inside the function disconnectWiFi() using removeNetworkSuggestions but the device still stays connected to the network. I tried passing a null ArrayList as well as a list that contains the NetworkSuggestion to the RemoveNetworkSuggestions function and neither of it fixed the problem.
public class SingleWifi extends AppCompatActivity {
private WifiManager wifiManager;
private Button disconnectButton;
List<WifiNetworkSuggestion> suggestionsList = new ArrayList<WifiNetworkSuggestion>();
#RequiresApi(api = Build.VERSION_CODES.Q)
#Override
protected void onCreate(Bundle savedInstanceState) {
wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_single_wifi);
String wifiSSID = getIntent().getStringExtra("wifiList");
connectToNetwork(wifiSSID);
disconnectButton = findViewById(R.id.disconnectBtn);
disconnectButton.setEnabled(false);
disconnectButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
disconnectWifi();
startActivity(new Intent(SingleWifi.this, MainActivity.class));
}
});
}
#RequiresApi(api = Build.VERSION_CODES.Q)
private void disconnectWifi() {
if(wifiManager != null) {
wifiManager.removeNetworkSuggestions(suggestionsList);
Toast.makeText(this,"Disconnect successful", Toast.LENGTH_SHORT).show();
}
}
#RequiresApi(api = Build.VERSION_CODES.Q)
private void connectToNetwork(String ssid) {
final WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
.setSsid(ssid)
.setWpa2Passphrase("password")
.setIsAppInteractionRequired(true)
.build();
int statusCode = wifiManager.removeNetworkSuggestions(suggestionsList);
suggestionsList.add(suggestion);
final WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
int status = wifiManager.addNetworkSuggestions(suggestionsList);
if (status == WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS) {
Toast.makeText(this, "Connection success", Toast.LENGTH_LONG).show();
}
else if(status == WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_DUPLICATE) {
Toast.makeText(this, "Already connected, update needed", Toast.LENGTH_LONG).show();
status = wifiManager.removeNetworkSuggestions(suggestionsList);
status = wifiManager.addNetworkSuggestions(suggestionsList);
}
final IntentFilter intentFilter = new IntentFilter(WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION);
final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override public void onReceive(Context context, Intent intent) {
if (!intent.getAction().equals(WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION)) {
return;
}
// Post connection
disconnectButton.setEnabled(true);
}
};
getApplicationContext().registerReceiver(broadcastReceiver, intentFilter);
}
}
removeNetworkSuggestions returns 0 so it does seem to produce the right output but does not seem to actually disconnect from the Internet.
I ended up going for a completely different implementation getting rid of the Wifinetworksuggestions API since this issue seem to be an unresolved bug as seen here: https://issuetracker.google.com/issues/140398818 So sadly, there is no fix for this issue as of now.
I'm trying to execute CheckInternetConnection class inside my main activity on create but when the oncreate is called the class is not getting launced however when i press back navigation button Main Activity successfully executes CheckInternetConnection :
Here's my code:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDrawer=findViewById(R.id.drawerlayout);
mDrawer.setTouchMode(ElasticDrawer.TOUCH_MODE_BEZEL);
Context context=this.getApplicationContext();
setupToolbar();
setupMenu();
search();
new CheckInternetConnection(this).checkConnection();
FragmentManager pr = getSupportFragmentManager();
ProjectListFragment prjlist = (ProjectListFragment)
pr.findFragmentById(R.id.frame);
if (prjlist == null) {
prjlist = new ProjectListFragment();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.setCustomAnimations(android.R.anim.fade_in,
android.R.anim.fade_out);
fragmentTransaction.commitAllowingStateLoss();
pr.beginTransaction().replace(R.id.id_main_frame, prjlist).commit();
}
public void onBackPressed() {
int count = getFragmentManager().getBackStackEntryCount();
if (count == 0) {
Intent intent=new Intent(MainActivity.this,MainActivity.class);//This intent will refresh mainactivity on back press
startActivity(intent);
finish();
//additional code
} else {
getFragmentManager().popBackStack();
finish();
}
}
This class will basically check for internet connection and display dialog if connection is not present.
public class CheckInternetConnection {
Context ctx;
public CheckInternetConnection(Context context){
ctx=context;
}
public void checkConnection(){
if(!isInternetConnected()) {
final FancyAlertDialog.Builder alert = new FancyAlertDialog.Builder(ctx)
.setBackgroundColor(R.color.colorAccent)
.setimageResource(R.drawable.internetconnection)
.setTextTitle("No Internet")
.setTextSubTitle("Cannot connect to server")
.setBody(R.string.noconnection)
.setPositiveButtonText("Connect Now")
.setNegativeButtonText("Go Offline")
.setOnNegativeClicked(new FancyAlertDialog.OnNegativeClicked() {
#Override
public void OnClick(View view, Dialog dialog) {
Intent in=new Intent(ctx,MainActivity.class);
in.putExtra("offline","offline");
ctx.startActivity(in);
dialog.dismiss();
}
})
.setPositiveColor(R.color.colorPrimaryDark)
.setOnPositiveClicked(new FancyAlertDialog.OnPositiveClicked() {
#Override
public void OnClick(View view, Dialog dialog) {
if(isInternetConnected()){
Intent in=new Intent(ctx,MainActivity.class);
ctx.startActivity(in);
dialog.dismiss();
}else {
Intent dialogIntent = new Intent(Settings.ACTION_SETTINGS);
dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
ctx.startActivity(dialogIntent);
}
}
})
.setBodyGravity(FancyAlertDialog.TextGravity.CENTER)
.setTitleGravity(FancyAlertDialog.TextGravity.CENTER)
.setSubtitleGravity(FancyAlertDialog.TextGravity.CENTER)
.setCancelable(false)
.build();
alert.show();
}
}
public boolean isInternetConnected() {
ConnectivityManager cm = (ConnectivityManager) ctx.getSystemService(Context.CONNECTIVITY_SERVICE);
return cm.getActiveNetworkInfo() != null
&& cm.getActiveNetworkInfo().isConnectedOrConnecting();
}
}
When I rotate my device, my activity instance is destroyed which starts a new onCreate. I can't figure out how to repopulate my RecyclerView after screen orientation. I have tried some solutions involing AndroidManifest: android:configChanges="keyboardHidden|orientation" and also with onSaveInstanceState, but could not get it to work. I have addedonSaveInstanceStateandonRestoreInstanceState` base code to my question, which does not do anything at the moment.
Thanks
MainActivity.java
public class MainActivity extends AppCompatActivity implements RepositoryAdapter.OnItemClickListener {
private static final String LOG_TAG = "MainActivity";
#BindView(R.id.fab_search_github_user)
FloatingActionButton fabSearchGitHubUser;
#BindView(R.id.et_search_user)
EditText etSearchUser;
#BindView(R.id.btn_search_user)
Button btnSearchUser;
#BindView(R.id.github_user)
TextView tvOwner;
#BindView(R.id.github_repository_recyclerview)
RecyclerView mRecyclerView;
private RepositoryAdapter mAdapter;
private Api mApi;
private Owner mOwner;
boolean isSearchToggled = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ButterKnife.bind(this);
mApi = ApiUtils.getApi();
// RecyclerView
RecyclerView.LayoutManager linearLayoutManager = new LinearLayoutManager(getApplicationContext());
mRecyclerView.setLayoutManager(linearLayoutManager);
mRecyclerView.setHasFixedSize(true);
// Floating action button to toggle user search field.
FloatingActionButton floatingActionButton = (FloatingActionButton) findViewById(R.id.fab_search_github_user);
floatingActionButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
toggleSearch();
}
});
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
}
#Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
}
#OnClick(R.id.btn_search_user)
public void onSearchBtnClicked(View view) {
if (!TextUtils.isEmpty(etSearchUser.getText())) {
String searchedUser = etSearchUser.getText().toString();
// Search will be done offline when no internet, otherwise online.
if (!isNetworkAvailable()) {
Toast.makeText(this, "No internet, searching offline", Toast.LENGTH_SHORT).show();
mOwner = Owner.getByUsername(searchedUser);
if (mOwner != null) {
searchByUsername(searchedUser);
tvOwner.setText(searchedUser);
} else {
if (mAdapter != null) {
mAdapter.clearRecyclerView();
}
tvOwner.setText(getString(R.string.user_not_found, searchedUser));
}
} else {
loadRepository(searchedUser);
tvOwner.setText(searchedUser);
Toast.makeText(this, "Searching online", Toast.LENGTH_SHORT).show();
}
} else {
Log.i(LOG_TAG, "Search field is empty");
}
if (view != null) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
toggleSearch();
}
/**
* Search local user by username.
*
* #param username The local user that is searched for.
*/
public void searchByUsername(String username) {
mAdapter = new RepositoryAdapter(Repository.getList(username), MainActivity.this);
mRecyclerView.setAdapter(mAdapter);
}
/**
* Search online on GitHub to retrieve all user repositories.
*
* #param username The GitHub user that is searched for.
*/
public void loadRepository(String username) {
mApi.listRepository(username).enqueue(new Callback<List<Repository>>() {
#Override
public void onResponse(Call<List<Repository>> call, Response<List<Repository>> response) {
mAdapter = new RepositoryAdapter(response.body(), MainActivity.this);
mRecyclerView.setAdapter(mAdapter);
}
#Override
public void onFailure(Call<List<Repository>> call, Throwable t) {
Log.e("MainActivity", "error loading from API");
}
});
}
#Override
public void onItemClick(Repository repository) {
if (isNetworkAvailable()) {
mOwner = Owner.getByUsername(repository.owner.getLogin());
Repository mRepository = Repository.getByRepositoryName(repository.getName());
if (mOwner != null) {
if (mRepository != null) {
// Repository is already in Database.
} else {
// Selected repository is added to Database
mRepository = new Repository(mOwner);
mRepository.setName(repository.getName());
mRepository.setLogin(repository.owner.getLogin());
mRepository.setDescription(repository.getDescription());
mRepository.setStargazersCount(repository.getStargazersCount());
mRepository.setForksCount(repository.getForksCount());
mRepository.save();
}
} else {
// selected repository and its owner are added to Database
mOwner = new Owner();
mOwner.setLogin(repository.owner.getLogin());
mOwner.setAvatarUrl(repository.owner.getAvatarUrl());
mOwner.setReposUrl(repository.owner.getReposUrl());
mOwner.save();
mRepository = new Repository(mOwner);
mRepository.setName(repository.getName());
mRepository.setLogin(repository.owner.getLogin());
mRepository.setDescription(repository.getDescription());
mRepository.setStargazersCount(repository.getStargazersCount());
mRepository.setForksCount(repository.getForksCount());
mRepository.save();
}
}
// Send intent with repository name to repository detail activity.
Intent intent = new Intent(MainActivity.this, RepositoryDetailActivity.class);
intent.putExtra(INTENT_KEY_REPOSITORY, repository.getName());
startActivity(intent);
}
/**
* Toggle search field according to its state.
*/
private void toggleSearch() {
if (!isSearchToggled) {
etSearchUser.setVisibility(View.VISIBLE);
btnSearchUser.setVisibility(View.VISIBLE);
isSearchToggled = true;
} else {
etSearchUser.setVisibility(View.GONE);
btnSearchUser.setVisibility(View.GONE);
isSearchToggled = false;
}
}
/**
* Checks if network is available on the device.
*
* #return Return when networkInfo is not null and networkInfo is connected.
*/
private boolean isNetworkAvailable() {
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
return networkInfo != null && networkInfo.isConnected();
}
}
configChanges also should include screenSize if you want turn off recreating activity class. So correct version:
android:configChanges="keyboardHidden|orientation|screenSize"
In order to save recycler view content without disabling recreating you have to store content in some place which is not bound to activity lifecycle or pass it to bundle in onSaveInstanceState and get it later in onRestoreInstanceState or in onCreate. Please, take a look at https://developer.android.com/guide/components/activities/activity-lifecycle.html
I'm working in an application that needs to do a background job every 5 seconds to retrieve an image from a server, when the job is done, the ImageView in my UI needs to be updated if there is something in return.
I'm using AlarmManager to do the job but don't know how to update the UI when the job is done.
Also I want to know if this is the best way to do it, or if I have to implement some kind of service.
This is my onCreate method, where I initialize my UI components and the AlarmManager with the PendingIntent:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
swtSIGNAL = (Switch) findViewById(R.id.swtSIGNAL);
snackView = swtSIGNAL;
swtSIGNAL.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (!isChecked) {
mSetSignalTask = new SetSignalAsync(progressDialog, snackView, true);
mSetSignalTask.execute();
} else {
mSetSignalTask = new SetSignalAsync(progressDialog, snackView, false);
mSetSignalTask.execute();
}
}
});
swtALARM=(Switch)findViewById(R.id.swtALARM);
snackView=swtALARM;
swtALARM.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (!isChecked) {
mSetAlarmTask = new SetAlarmAsync(progressDialog, snackView,true);
mSetAlarmTask.execute();
} else {
mSetAlarmTask = new SetAlarmAsync(progressDialog,snackView,false);
mSetAlarmTask.execute();
}
}
});
imgFOTO=(ImageView) findViewById(R.id.imgFOTO);
progressDialog = new ProgressDialog(this);
progressDialog.setCancelable(false);
progressDialog.isIndeterminate();
callListener = new EndCallListener();
telephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
telephonyManager.listen(callListener, PhoneStateListener.LISTEN_CALL_STATE);
Intent alarmIntent = new Intent(this, AlarmReceiver.class);
pendingIntent = PendingIntent.getBroadcast(this, 0, alarmIntent, 0);
}
This is my setAlarm method which activates the AlarmManager:
public void setAlarm(){
manager=(AlarmManager)getSystemService(ALARM_SERVICE);
int interval=5000;
manager.setRepeating(AlarmManager.RTC_WAKEUP,System.currentTimeMillis(),interval,pendingIntent);
Toast.makeText(this, "Alarm Set", Toast.LENGTH_SHORT).show();
}
This is the AlarmReceiver class which extends from a BroadcastReceiver:
public class AlarmReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Working", Toast.LENGTH_SHORT).show();
}
}
Finally this is the method that fetches the image from the server; I'm using AsyncTask to not freeze the app.
public class GetImageAsync extends AsyncTask<Void,Void,Bitmap>{
#Override
protected Bitmap doInBackground(Void... params) {
try{
URL url=new URL("http://192.168.0.16/HouseSecure/SECImages/example.jpg");
HttpURLConnection connection=(HttpURLConnection)url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream inputStream=connection.getInputStream();
Bitmap image= BitmapFactory.decodeStream(inputStream);
connection.disconnect();
return image;
}catch (MalformedURLException e){
Log.e(LOG_TAG, e.getMessage());
return null;
}catch(IOException ex){
Log.e(LOG_TAG,ex.getMessage());
return null;
}
}
#Override
protected void onPostExecute(Bitmap image) {
imgFOTO.setImageBitmap(image);
}
}
Use AlarmClock API Provided by Studio instead of AlarmManager if you are going to set an Alarm