How to load data to app widget after device boot - android

I'm trying to read data to my widget after device boot.
My boot receiver is this:
public class onBootReceiver extends BroadcastReceiver{
public static final String TAG = "BootReceiver";
private Context c;
#Override
public void onReceive(Context c, Intent i) {
// TODO Auto-generated method stub
boolean dontStop = true;
while(dontStop)
{
try
{
this.c=c;
if(isExternalStorageMounted())
{
dontStop = false;
}
else
for(int j=0;j<10000;j++)
Log.d(TAG, "###################### EXTERNAL STORAGE NOT MOUNTED ##########################");
}
catch (Exception e)
{
for(int j=0;j<10000;j++)
Log.d(TAG, "###################### EXTERNAL STORAGE NOT MOUNTED ##########################");
}
}
Intent externalStorageReady = new Intent(c, TheWidget.class);
externalStorageReady.setAction(GlobalVars.WIDGET_INTENT_ACTION_READ_PREFS_AFTER_BOOT);
c.sendBroadcast(externalStorageReady);
}
private boolean isExternalStorageMounted()
{
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_REMOVED.equals(state))
{
return false;
}
else if (Environment.MEDIA_SHARED.equals(state))
{
return false;
}
else if (Environment.MEDIA_UNMOUNTABLE.equals(state))
{
return false;
}
else if (Environment.MEDIA_UNMOUNTED.equals(state))
{
return false;
}
return true;
}
}
I know I get the BOOT_COMPLETED intent (after using it in the widget itself), but I just can't read my saved data.
I read that using SharedPreferences is the solution, but what I know is when you boot your device, the SharedPreferences is no longer there.
I save the data internally using built-in SQL in the Android SDK.
Please help... :(

External storage may not be ready by the time of a BOOT_COMPLETED broadcast. And your loops are pointless.
but what i know is when you boot your device, the SharedPreferences is no longer there.
Yes, SharedPreferences are there at boot time.
i save the data internally using built-in SQL in the android sdk.
Then it is unclear why you are waiting on external storage, since your data is not on external storage.
Any form of I/O may take too long, though, right at boot time. Have your BroadcastReceiver call startService() on an IntentService that can read your database or SharedPreferences in onHandleIntent() and update your app widget.

Related

How to check screen unlock type of device

I have search a lot but my query not match to it, i found the solution for lock and unlock the phone
Like this way I have created my broadcast with the 3 filters which I recieved:
public class ScreenReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
Log.e(TAG, "In Method: ACTION_SCREEN_OFF");
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
Log.e(TAG, "In Method: ACTION_SCREEN_ON");
} else if (intent.getAction().equals(Intent.ACTION_USER_PRESENT)) {
Log.e(TAG, "In Method: ACTION_USER_PRESENT");
}
}
}
I need to find out the way user is unlock screen with it type. if user has unlocked screen by using the password or pattern or fingerprint or by button.
So I am not able to get the particular event from which I can get the follow output.
So kindle help to go in the right direction.
To detect lock pattern I have used below code.So, I think it also help you.you can use Settings.Secure.LOCK_PATTERN_ENABLED flag. Show below:-
private static boolean CheckPatternSet(Context context)
{
ContentResolver contentResolver = context.getContentResolver();
try
{
int lockEnabled = Settings.Secure.getInt(contentResolver, Settings.Secure.LOCK_PATTERN_ENABLED);
return lockEnabled == 1;
}
catch (Settings.SettingNotFoundException e)
{
return false;
}
}
For More understanding you can show below stackoverflow link :-
Android check if lockscreen is set

Interprocess or adb communication with AndroidJUnit

I want to know, does any way exist to communicate with system during instrumentation test execution.
For example:
I have a phone with IR port on onboard & I can work with it through private SDK, also I can tune it with my application. In my Instrumentation test cases I want test app behavior based on external events which I want to configure before test separate test execution.
It's looks like
#Test
public void test() throws Exception {
setupExternalCondition(condition1_ON); // setup external transiver
assertNotNull(IR.read());
assertTrue(assertIR.write());
setupExternalCondition(condition1_OFF);
assertNotNull(IR.read());
assertFalse(IR.write());
}
It's very simple example but there is a lot of "conditions", and sdk updating frequencies to high. I can't do all of this verification manually, and can't ask "transiver&SDK team" make a mock states list for writing just a unit test for coverage. So I want somehow inject external component execution to TestRuner for receiving events(or testName before test case execution) on local machine(or CI machine) to setup external condition.
Simple solution(I think) to run a tcp server on appUnderTest and request external condition change - I am not sure does it possible, and not sure about stable connection(wifi), so may be it's possible to do over adb.
Any suggestions?
P.S: test device has root permissions.
So, find not bad but not ideal solution.
Still wait for better proposition, if not may be this answer will be helpful for someone;
For "building the bridge" between local machine and AndroidJUnitTest I add next class to tests:
class IPCServiceBridge extends BroadcastReceiver {
private static final String FILTER_ID = "IPC_SERVICE";
private static IPCServiceBridge sInstance;
private boolean mIsPermitted;
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("ipc.service.action")) {
mIsPermitted = true;
}
}
public static IPCServiceBridge getInstance() {
if (sInstance == null) {
sInstance = new IPCServiceBridge();
IntentFilter filter = new IntentFilter();
filter.addAction("ipc.service.action");
Context context = InstrumentationRegistry.getContext();
context.registerReceiver(sInstance, filter);
}
return sInstance;
}
public void sendIpcCommand(String commandName) {
try {
int i = 30;
mIsPermitted = false;
while (i > 0) {
pub("request:" + commandName);
Thread.sleep(1000);
if (mIsPermitted) {
break;
}
i--;
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
if (!mIsPermitted) {
throw new RuntimeException("IPC service does not respond");
}
}
private static void pub(String msg) {
Log.e(FILTER_ID, msg);
}
}
Than I start adb logcat -s "filter_name", parse and check which condition should be applied for InsttUnit test. When conditions is ready i send back broadcast receiver with required action.
#Test
public void test2() throws Exception {
IPCServiceBridge.getInstance().sendIpcCommand("CONDITION#123");
}
Work good, but I'm not sure that it will be super stable.

Run Service only when on Wifi if user wants to

I made an app whos purpose is to download and set wallpaper in set intervals.
User can choose to do that only when connected to wifi or not.
Relevant code:
mWallpaperButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mSwitchWifi.isChecked()) {
mConnectivity = mConnectionDetector.isConnectedToWifi();
} else {
mConnectivity = mConnectionDetector.isConnectedToInternet();
}
if (mConnectivity) {
my code here
}
The code above works fine for setting the wallpaper the first time.
My problem is, I need the Service to check if the user wants to update wallpaper only over WIFI before doing so. At the moment, wallpaper is updated regardless of mSwitchWifi state. (which is bad, because it can use mobile data and user sometimes doesn't want that.)
I tried running similar Switch code in Service but I can't because it must be called in a UI Thread.
I also tried couple of workarounds and Intent.putExtra but I get exception:
NullPointerException: Attempt to invoke virtual method on a null object reference
Any idea how to check network state in service?
My service code atm:
public static class Service extends IntentService {
public Service() {
super("wallpaperchanger-download");
}
#Override
protected void onHandleIntent(Intent intent) {
if (url == null) {
SharedPreferences sharedPreferences = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
String getUrl = sharedPreferences.getString(pref_urlKey, null);
if (getUrl != null) {
url = getUrl;
}
}
wm = WallpaperManager.getInstance(this);
try {
InputStream input = new URL(url).openStream();
Log.v(TAG, url);
wm.setStream(input);
input.close();
} catch (Exception e) {
e.printStackTrace();
}
loading = false;
Log.v(TAG, "Service Running Url " + url);
}
}
If you question is how to access the user selection inside a service/runnable/thread then you can use shared preferences to achieve this. So in your case when the user selects the choice for the first time you want to do something like this:
if(mSwitchWifi.isChecked()) { // i guess this is no wifi
SharedPreferences sharedPreferences = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
Editor editor = sharedPeredences.edit()
editor.putBoolean("isWifi", false)
} else { // guessing this is wifi
SharedPreferences sharedPreferences = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
Editor editor = sharedPeredences.edit()
editor.putBoolean("isWifi", true)
}
This is this code to check if it is true or false:
mWallpaperButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Boolean isWifi = isWifi()
if (!isWifi) { // i guess this is if not wifi
mConnectivity = mConnectionDetector.isConnectedToWifi();
} else if (isWifi) { // guessing this is wifi
mConnectivity = mConnectionDetector.isConnectedToInternet();
}
}
}
public Boolean isWifi() { // you can call this inside your service
SharedPreferences sharedPreferences = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
Boolean wifiState = sharedPreferences.getBoolean("isWifi", true)
return wifiState;
}
This is just a very rough implementation to give an idea of how you can do it, you can improve this many ways. For example you could put the if statement thats inside the onClickListener in the isWifi() function and just call isWifi() inside your runnable/thread...
you can set list preferences to auto update functions based on the network ....
You can create separate class to check the connectivity and from that class you can select the preferences like auto update only on wifi or when connected to network or do not auto update ....

How to display message to all users my application?

I need to implement functionality to display application news/announcements for all users.
I will do it rarely so push notification is not for me.
Are there any library or sample, how to implement this fast and easy? Or better will be to implement it in next way:
When application starts - read html file on server, if file was updated after the last attempt - display content of file in popup.
All you need is to load an html, or better, a simple text file containing the notification index like:
in yourdomain.com/notificationnumber.txt
contains
"4"
Check in your applications, probably simply using SharedPreferences for the last displayed version. Then load all notification, for example:
yourdomain.com/notification3.html
yourdomain.com/notification4.html
Display them and store the index number to know which notifcations have been shown to the user. There are no special libraries needed for such a task.
If the announcements are not very frequent, then checking the html file on the server each time the application is launched is good enough.
I feel like it depends on the styling options, which your notifications require:
if no rich styling is needed, you could simply check an XML-file, Text-file or similar for some notification information (Texts, notification coded) as bjornson proposed and then just show an AlertDialog with the specific information.
If you require rich styling, you may need to load the content from a server by utilizing a WebView. So for example your app's frontpage could partly consist of a WebView that in specific cases shows the news, which you intend to present to the user. Please note, that the WebView-technique is/was used by Facebook to update certain parts of their apps without the troubles of releasing a new version in the various App Stores.
I have used an rss-feed from a wordpress blog for this, if there is a new entry, a webview is opened and the new entry is displayed. Instead of displaying the entry, one could just parse the data and display ist (using jdom or other libraries to read the html document) We use IntentService to check once every hour, but you could just do it once on strartup.
So the Service is build like this:
public class UpdateService extends IntentService
{
//INtent Services have a constructer where you have to pass a String to the super class.
public UpdateService()
{
super("UpdateService");
}
#Override
public IBinder onBind(Intent intent)
{
return null;
}
#Override
public void onCreate()
{
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
super.onStartCommand(intent, flags, startId);
return Service.START_NOT_STICKY;
}
#Override
public void onDestroy()
{
super.onDestroy();
}
//This method downloads the file from a url and checks if its well formed. It has its own thread because android does not allow access to the internet in the same thread
private void checkfornews()
{
final SAXBuilder builder = new SAXBuilder();
new Thread(new Runnable()
{
public void run()
{
// command line should offer URIs or file names
try
{
Document doc = builder.build(url);
Element root = doc.getRootElement();
readnews(root);
// If there are no well-formedness errors,
// then no exception is thrown
}
// indicates a well-formedness error
catch (JDOMException e)
{
}
catch (IOException e)
{
}
}
}).start();
}
}
//checking for the lateste link, if its a new one we have a new link to show
private void readnews(Element root)
{
List<Element> children = root.getChildren();
Iterator<Element> childrenIterator = children.iterator();
while(childrenIterator.hasNext())
{
Element child = childrenIterator.next();
List<Element> grandchildren = child.getChildren();
Iterator<Element> grandchildrenIterator = grandchildren.iterator();
int counter=0;
while(grandchildrenIterator.hasNext())
{
Element grandchild = grandchildrenIterator.next();
String name = grandchild.getName();
if(name.equals("item") && counter ==0)
{
String title="";
String link="";
String category="";
List<Element> ggc = grandchild.getChildren();
Iterator<Element> ggci= ggc.iterator();
while(ggci.hasNext())
{
Element ggch = ggci.next();
if((ggch.getName()).equals("title"))
{
title=ggch.getText();
}
if(ggch.getName().equals("link"))
{
link=ggch.getText();
}
if(ggch.getName().equals("category"))
{
category=ggch.getText();
}
}
if(category.equals("SoundOfTheCity"))
{
counter++;
Logging.i(TAG, "found some news");
String latestnews = prefs.getString("SOTCNews", "");
if(!(latestnews.equals(link)))
{
Logging.i(TAG, "and its new");
Editor edit = prefs.edit();
edit.putString("SOTCNews", link);
edit.commit();
showNotification(title, link);
}
}
}
}
}
}
private void showNotification(String title, String link)
{
//do what needs to be done with the new data
}
#Override
protected void onHandleIntent(Intent intent)
{
checkfornews();
scheduleNext();
}
private void scheduleNext()
{
int checkingDelay = UPDATE_DELAY;
Calendar cal = Calendar.getInstance();
cal.add(Calendar.HOUR, checkingDelay);
Intent intent = new Intent(this, UpdateService.class);
PendingIntent pendingIntent = PendingIntent.getService(this, UPDATEALARM, intent, 0);
AlarmManager am = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);
}
}
depending on the form of the html file you have to redo the readnews method and then the showNotification method.
If you don't want to have a backend like wordpress (or use a blog-like feature) you could just store the content of a static webpage instead of the url and if this content changes, use the showNotification method. This would probably do the trick and is a lot less work.

ActivityWatcher & ProcessObserver

I would like to know the purpose of foloowing two files:
frameworks/base/core/java/android/app/IActivityWatcher.aidl
[description: Callback interface to watch the user's traversal through activities.]
frameworks/base/core/java/android/app/IProcessObserver.aidl
[no description]
I am trying to build an app wherein user can decide which apps can be run during particular period of time (say, from 10am till 4pm).
Is there any way where my app will get notified if one the apps specified by the user starts? This way my app can send kill command (I am assuming that root access is available.)
It seems that IActivityWatcher has been removed beginning with JellyBean, in order to monitor which Activity is running foreground, you can use IProcessObserver as following:
mActivityManagerNative = ActivityManagerNative.getDefault();
if (mActivityManagerNative != null) {
try {
mActivityManagerNative.registerProcessObserver(mProcessObserver);
} catch (RemoteException e) {
Log.e("TAG", "onCreate() RemoteException!");
}
}
private IProcessObserver.Stub mProcessObserver = new IProcessObserver.Stub() {
#Override
public void onForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) {
doWhatUWantHere();
}
#Override
public void onImportanceChanged(int pid, int uid, int importance) {
}
#Override
public void onProcessDied(int pid, int uid) {
}
};
P.S.
You can use following code snippets to get the package name of foreground running Activity:
private String getForegroundPackage() {
ActivityManager am = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
List<RecentTaskInfo> taskInfo = am.getRecentTasks(1,
ActivityManager.RECENT_IGNORE_UNAVAILABLE);
return taskInfo.isEmpty()
? null : taskInfo.get(0).baseIntent.getComponent().getPackageName();
}

Categories

Resources