In my code, I am starting timerTask when broadcast message received.
Here I displayed code of two classes.
1. broadcast receiver.
2. XML parsing.
my Question is when I call timerTask, at scheduled time Timer call & I get all data into xml class.Like "mServiceList" .But When I want to use this array every time it is getting null.
I am not sure where I am doing wrong.
If any body have idea, then its great.
public class MyWidgetIntentReceiver extends BroadcastReceiver {
public static int clickCount = 0;
private String msg[] = null;
private ParsingXML myXMLHandler;
private ArrayList<Stream> mServiceList = new ArrayList<Stream>();
private UrlTimerTask mUrlTimerTask = null;
private Timer mTimer = null;
private String rssFeed = "https;??.....";
#Override
public void onReceive(Context context, Intent intent) {
mUrlTimerTask = new UrlTimerTask();
mTimer = new Timer();
mTimer.scheduleAtFixedRate(mUrlTimerTask, 0, 120000); // (60*2*1000)
if (intent.getAction().equals(WidgetUtils.WIDGET_UPDATE_ACTION1)) {
Toast.makeText(context, "NEXT!!", Toast.LENGTH_SHORT).show();
updatePreviousWidgetListener(context);
}
}
private void updatePreviousWidgetListener(Context context) {
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
R.layout.widget_layout);
// updating view
remoteViews.setTextViewText(R.id.title, getNextTitle(context));
remoteViews.setTextViewText(R.id.desc, getDesc(context));
// re-registering for click listener
remoteViews.setOnClickPendingIntent(R.id.sync_button,
MyWidgetProvider.buildButtonPendingIntent(context));
// re-registering for click listener
remoteViews.setOnClickPendingIntent(R.id.next,
MyWidgetProvider.buildNextButtonPendingIntent(context));
MyWidgetProvider.pushWidgetUpdate(context.getApplicationContext(),
remoteViews);
}
private String getDesc(Context context) {
// some static jokes from xml
msg = context.getResources().getStringArray(R.array.news_headlines);
if (clickCount >= msg.length) {
clickCount = 0;
}
return msg[clickCount];
}
private String getNextTitle(Context context) {
if (mServiceList != null && mServiceList.size() > 0) {
return mServiceList.get(clickCount).getTitle().toString();
} else {
mStreamList = myXMLHandler.getItemsList();
Toast.makeText(context, "no data found", Toast.LENGTH_SHORT).show();
return "no data";
}
}
private class UrlTimerTask extends TimerTask {
#Override
public void run() {
try {
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
myXMLHandler = new ParsingXML();
xr.setContentHandler(myXMLHandler);
URL _url = new URL(rssFeed);
xr.parse(new InputSource(_url.openStream()));
mServiceList = myXMLHandler.getItemsList();
if (!mServiceList.isEmpty()) {
for (int i = 0; i < mServiceList.size(); i++) {
Log.d(TAG, mServiceList.get(i).getTitle());
}
}
} catch (ParserConfigurationException pce) {
Log.e("SAX XML", "sax parse error", pce);
} catch (SAXException se) {
Log.e("SAX XML", "sax error", se);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Still you have any query regarding to understand my question pls tell me I will try my best to understand my query. because I want answer.
Short Note : I want to use parsing data into broadcast receiver class.
Thanks,
I couldn't understand, in your BroadcastReceiver's onReceive(Context context, Intent intent) , you called updatePreviousWidgetListener(context); this method. But rest of your code shows no call to this method.
If I am not wrong, you have called wrong method in onReceive(Context context, Intent intent). When does updatePreviousWidgetListener(context); get called?
Correct me if I am wrong.
Related
I would like to update a view from within an open activity when the device receives a push notification.
When a push notification is received the updateBalance function is executed,
a mysql database is queried and an amount is returned.
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private void updateBalance(String messageBody) {
h1 = new Handler(Looper.getMainLooper()) {
#Override
public void handleMessage(Message msg) {
bb = msg.getData();
String str = bb.getString("result");
Log.d(TAG,str);
Message msg=handler.obtainMessage()
}
};
t = new Thread(new MyRunnable(h1));
t.start();
try {
t.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
I have another class
public class MyRunnable implements Runnable {
private Handler h2;
public MyRunnable(Handler h) {
this.h2 = h;
}
#Override
public void run() {
String name = "w12";
BalanceActivity NB = new BalanceActivity(name);
Message m = Message.obtain();
Bundle b = new Bundle();
b.putString("result", "10");
m.setData(b);
h2.sendMessage(m);
}
}
I have a MainActivity that I would like to update after the amount is returned. How would I do this possibly with another Handler and Runnable.
public class MainActivity extends Activity {
TextView TV = (TextView) findViewById(package.name.R.id.Balance);
}
Try to check your activity is currently in foreground. if yes then create method where you can update your view.
public static boolean isServiceRunning(Context context) {
Log.i(TAG, "Checking if service is running");
ActivityManager activityManager = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningServiceInfo> services = activityManager.getRunningServices(Integer.MAX_VALUE);
boolean isServiceFound = false;
for (int i = 0; i < services.size(); i++) {
if (Constants.PACKAGE.equals(services.get(i).service.getPackageName())){
if (Constants.BACKGROUND_SERVICE_CLASS.equals(services.get(i).service.getClassName())){
isServiceFound = true;
}
}
}
Log.i(TAG, "Service was" + (isServiceFound ? "" : " not") + " running");
return isServiceFound;
}
Make use of Broadcast Receivers. Register local broadcast receiver in activity. Broadcast data when notification received.
I have a classe for download files by an executor :
this.getFreshGoolgletoken(new CallBackTokenRefresh() {
#Override
public void getFreshGoogleToken(String token,String userEmail) {
ArrayList<ExecuteSynchroneRequest> mesRequetes = new ArrayList<>();
Intent mServiceIntent = new Intent(context, TraitementPermisLoaded.class);
for (CollectionPermis permis : collectionPermis){
// stocker les permis + les s3Key
int revision = permis.revision;
final String uuid = permis.uuid;
Log.i(LOG_TAG,"synchro OnLoop permis num & revision :"+uuid+"/"+revision);
Map<String,String> params = new HashMap<>();
params.put("uuid",uuid);
params.put("revision",String.valueOf(revision));
mesRequetes.add(new ExecuteSynchroneRequest(AwsEworkPermitsRoutes.PERMITS,params,context,token,apiClient,uuid,handler,mServiceIntent,callBack));
}
ExecutorService execute = Executors.newSingleThreadExecutor();
for(Runnable r : mesRequetes){
execute.execute(r);
}
execute.shutdown();
}
In this methode i have an IntentService(mServiceIntent) for handle a long treatement on my download. My executor class handle intentService like this in switch command :
case PERMITS:
if(mServiceIntent == null) break;
mServiceIntent.setData(Uri.parse(responseData));
mServiceIntent.putExtra("myHandler", new Messenger(handler));
mServiceIntent.putExtra("ptUuid", uuid);
context.startService(mServiceIntent);
break;
mServiceIntent Class is :
public class TraitementPermisLoaded extends IntentService {
static final String LOG_TAG = "ewp-executor ";
SharedPreferences sharedPreferences;
Handler handler;
public TraitementPermisLoaded() {
super("TraitementPermisLoaded");
setIntentRedelivery(true);
Log.i(LOG_TAG," service traitement permis called 2 ");
}
#Override
protected void onHandleIntent(Intent workIntent) {
this.sharedPreferences = getApplicationContext().getSharedPreferences("DATA", Context.MODE_PRIVATE);
// Gets data from the incoming Intent
String responseData = workIntent.getDataString();
Messenger messenger = null;
String ptUuid = "";
Bundle extras=workIntent.getExtras();
if (extras!=null) {
messenger=(Messenger)extras.get("myHandler");
ptUuid = extras.getString("ptUuid");
}
String permisUuid = "";
PtWrapper pt = null;
try {
ObjectMapper mapper = new ObjectMapper();
pt = mapper.readValue(responseData, PtWrapper.class);
HandleJson handleJson = HandleJson.getInstance(getApplicationContext());
permisUuid = pt.getPermisTravailFormContext().permisTravail.uuid;
if (permisUuid != null) {
handleJson.writeInInterneFileSysteme(sharedPreferences.getString("email",null),pt, permisUuid);
} else {
throw new HandleJsonNoPermisException("le UUID est null on ne peut pas enregistrer ce permis");
}
handleJson.setKpi(pt);
Message message = Message.obtain();
Bundle bundle= new Bundle();
bundle.putString("myevent", "un permis ok");
message.setData(bundle);
messenger.send(message);
} catch (IOException e) {
Log.i(LOG_TAG, e.getMessage());
e.printStackTrace();
Message message = Message.obtain();
Bundle bundle= new Bundle();
bundle.putString("error", ErrorsCodes.CODE_40.toString()+" / permit uuid : "+ptUuid);
message.setData(bundle);
try {
messenger.send(message);
} catch (RemoteException e1) {
e1.printStackTrace();
Log.i(LOG_TAG,"erreur messager : "+e1.getMessage());
}
} catch (HandleJsonNoPermisException e) {
Log.i(LOG_TAG, e.getMessage());
e.printStackTrace();
} catch (RemoteException e) {
Log.i(LOG_TAG,e.getMessage());
e.printStackTrace();
}catch(Exception e){
Log.i(LOG_TAG,e.getMessage());
e.printStackTrace();
}
}
}
I load 27 files but only 14 get a treatment, the Intentservice stop to work, it'seems to be after activity change but not sure. After loaded files, I change my activity by another, but intentService get all request in the queue. I have use IntentService because it will finish working all process before stopping?
What did I do wrong?
Thanks
the error source is the size of data in myService.setData(mydata>250ko). For all data more than 250 ko the service stop with this error message :
A/ActivityManager: Service done with onDestroy, but executeNesting=2:
ServiceRecord{5c8e958 u0
com.alit.aws.android.eworkpermit/.lib.TraitementPermisLoaded
There is another way to pass large data more than 250 k to my intentService ? I have tried :
->mServiceIntent.setData(Uri.parse(responseData));
->mServiceIntent.putExtra("myData",responseData);
I have found a solution, remove the "setData(responseData)" and replace it by a globalHasMap. After the end of treatment I remove item in hashMap.
May be it's not awesome but i have not found a better solution.
If someone can show me a better way, do it ;-)
Thanks
Is there any way to directly communicate with a WallpaperService from an Activity? It doesn't look like I can use the normal service communication classes because the onBind method is declared final in the WallpaperService class I'm extending. Worth noting that I'm referring to my WallpaperService not any.
Any workarounds if this isn't possible?
My solution was to use local sockets. I created an instance of a LocalServerSocket in the constructor of my wallpaper's Engine. Here's a quick implementation. Server runs on a separate thread and is directly tied to the lifecycle of MyEngine. The thread will stop when continueSocket is set to false. This happens onDestroy. Problem is that LocalServerSocket.accept() blocks until there's something to do. The workaround is to send a message to our own server so it will run through the loop again and check continueSocket (which is now false), closing the server. Check the closeSocketServer method. I have it running in onDestroy in the example but you might want to use it elsewhere like onSurfaceDestroyed and add your own sanity checks.
public class MyWallpaperService extends WallpaperService {
#Override
public Engine onCreateEngine() {
return new MyEngine();
}
private class MyEngine extends Engine {
private boolean continueSocket = true;
MyEngine() {
new Thread() {
#Override
public void run() {
try {
LocalServerSocket server = new LocalServerSocket("MyAddress");
Log.d("SERVER READY", "Server is ready.");
while(continueSocket) {
LocalSocket receiver = server.accept();
if(receiver != null) {
InputStream input = receiver.getInputStream();
byte[] data = IOUtils.toByteArray(input);
Log.d("GOT DATA", new String(data));
}
}
server.close();
} catch (IOException ex) {
Log.wtf("IOEXCEPTION", ex);
}
}
}.start();
}
#Override
public void onDestroy() {
closeSocketServer();
super.onDestroy();
}
private void closeSocketServer() {
continueSocket = false;
try {
LocalSocket socket = new LocalSocket();
socket.connect(new LocalSocketAddress("MyAddress"));
socket.getOutputStream().write(new byte[0]);
socket.getOutputStream().close();
socket.close();
} catch (IOException ex) {
//
}
}
}
}
And in my Activity it can be as simple as this...
try {
LocalSocket sender = new LocalSocket();
sender.connect(new LocalSocketAddress("MyAddress"));
String data = "Hello world!";
Log.d("SENT DATA", data);
sender.getOutputStream().write(data.getBytes());
sender.getOutputStream().close();
sender.close();
} catch (IOException ex) {
Log.wtf("IOEXCEPTION", ex);
}
Logcat ends up looking like this:
D/SERVER READY﹕ Server is ready. (when the wallpaper starts up)
D/SENT DATA﹕ Hello world! (when the activity sends data)
D/GOT DATA﹕ Hello world! (when the wallpaper gets the data)
In your WallpaperService onCreateEngine:
IntentFilter intentFilter = new IntentFilter("your.package.your.action");
MyBroadcastReceiver mReceiver = new MyBroadcastReceiver(mRenderer);
LocalBroadcastManager.getInstance(getApplicationContext())
.registerReceiver(mReceiver, intentFilter);
In mRenderer's class:
public void receiveCommand(int i) {
Log.d("got", String.valueOf(i));
}
Receiver class:
public class MyBroadcastReceiver extends BroadcastReceiver {
private final MyRenderer _mRenderer;
public MyBroadcastReceiver(MyRenderer mRenderer) {
_mRenderer = mRenderer;
}
#Override
public void onReceive(Context context, Intent intent) {
_mRenderer.receiveCommand(intent.getExtra("msg", -1));
}
}
Now call from activity:
Intent in = new Intent();
in.setAction("your.package.your.action");
in.setExtra("msg", 42);
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(in);
I'm trying to implement a service to handle the communication with the server for the following code. I don't know much about the design architecture for these.
Here is my service class
public class BgService extends Service {
private static final String TAG = BgService.class.getSimpleName();
private Timer timer;
SendJsonRequest sjr;
private TimerTask updateTask = new TimerTask(){
#Override
public void run(){
try{
SendJsonRequest sjr = new SendJsonRequest();
sjr.carMake();
Log.i(TAG, "LOOK AT ME");
}
catch(Exception e){
Log.w(TAG,e);
}
}
};
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate(){
super.onCreate();
Log.i(TAG, "Service creating");
timer = new Timer("Server listening timer");
timer.schedule(updateTask, 1000L, 60*1000L);
}
#Override
public void onDestroy(){
super.onDestroy();
Log.i(TAG, "Service Destroying");
timer.cancel();
timer = null;
}
}
Here is my SendJsonRequest class
public class SendJsonRequest{
private static final String TAG = "SendJsonRequest";
private static String URL = "xxxxxxxxx";
private static String infoRec;
public static void createJsonObj(String path, Map x){
infoRec = CreateJsonRequest.jsonRequest(URL+path, x );
System.out.println(infoRec);
}
public static void carMake(){
String path = "/CarMake";
Map<String, Object> z = new HashMap<String,Object>();
z.put("Name", "Ford");
z.put("Model", "Mustang");
createJsonObj(path, z);
}
}
Here is my CreateJsonObject class
public class CreateJsonRequest {
public static String jsonRequest(String URL, Map<String,Object> params){
try{
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(URL);
JSONObject holder = new JSONObject();
for (Map.Entry<String, Object> m : params.entrySet()){
try {
holder.put(m.getKey(), m.getValue());
}
catch (JSONException e) {
Log.e("Hmmmm", "JSONException : "+e);
}
}
StringEntity se;
se = new StringEntity(holder.toString());
httpPost.setEntity(se);
httpPost.setHeader("Accept", "text/json");
httpPost.setHeader("Content-type", "text/json");
HttpResponse response = (HttpResponse) httpClient.execute(httpPost);
HttpEntity entity = response.getEntity();
if(entity != null){
InputStream is = entity.getContent();
Header contentEncoding = response.getFirstHeader("Content-Encoding");
String result= convertToString(is);
is.close();
System.out.println(result);
return result;
}
}
catch(Exception e)
{
e.printStackTrace();
}
return null;
}
Sorry for the massive amount of code. How I implemented my service is obviously not correct, I just have no clue where to start to get a service handling the json requests to the server. Thanks in advance.
To be more clear, this did work on a button click, now I'm trying to get it to all run in the background with the service. So I guess my question is what goes where in the service?
My activity successfully starts the service, the service would work and print "look at me" to the logcat every minute. Then I added the try{ sjr.carMake()} and it catches an exception.
You can use a broadcast receiver. This is a way to have your code start at certain times indicated by Android OS - for example, you can have it start when Android finished booting up (this is where I run my services usually.
The best way is to use the AlarmManager class, and tell your service how often to run.
Tell us more about what you're trying to do, and what the problem is, and we can give you a more concise answer...
UPDATE:
Have you created an entry in the manifest.xml file for the service?
UPDATE
Here is how I'm doing it in my application. This is your "hook" to the OS. It's going to fire when it finishes booting (don't forget to make in entry in the manifest for this!)
public class TmBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(final Context context, final Intent bootintent) {
try{
Log.i("Taskmotion-ROBOT", "Robot Broadcast signal received on Boot. Trying to start Alarm scheduler");
Intent mServiceIntent = new Intent(context, ServiceAlarm.class);
context.startService(mServiceIntent);
}
catch(Exception e)
{
Log.i("Taskmotion", "Failed to start service...");
}
}
}
This Broadcast receiver calls a service that implements the AlarmManager class. The alarm manager sets up a schedule to run my service at a specified interval. Note that the alarms are deleted when the phone is shut down - but then recreated again when process is repeated as the phone boots back up and runs the BroadcastReceiver again.
public class ServiceAlarm extends Service {
private PendingIntent mAlarmSender;
#Override
public void onCreate() {
try{
Log.i("Taskmotion-ROBOT", "Setting Service Alarm Step 1");
mAlarmSender = PendingIntent.getService(this.getApplicationContext(),
0, new Intent(this.getApplicationContext(), BackgroundService.class), 0);
}
catch(Exception e)
{
Log.i("Taskmotion-ROBOT", "Problem at 1 :" + e.toString());
}
long firstTime = SystemClock.elapsedRealtime();
Log.i("Taskmotion-ROBOT", "Setting Service Alarm Step 2");
// Schedule the alarm!
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
am.setRepeating(AlarmManager.ELAPSED_REALTIME,
firstTime, AlarmManager.INTERVAL_HOUR, mAlarmSender);
this.stopSelf();
}
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
}
I haven't refactored this code yet, it was my first go at it. I see now that I'm looking at it again that I could probably do the scheduling inside the BroadcastReceiver, but for the sake of getting you something that works, I'll continue.
As indicated by AlarmManager.INTERVAL_HOUR, my service will run once an hour. The service that I want to run is defined in the pendingIntent (BackgroundService.class). This is where you put your own service class.
I reworked your service class for you, and removed the timer (functionality replaced by the BroadcastReceiver & AlarmManager).
public class BgService extends Service {
private static final String TAG = BgService.class.getSimpleName();
SendJsonRequest sjr;
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate(){
super.onCreate();
Log.i(TAG, "Service creating");
//DO YOUR WORK WITH YOUR JSON CLASS HERE
//**************************************
//Make sure to call stopSelf() or your service will run in the background, chewing up
//battery life like rocky mountain oysters!
this.stopSelf();
}
#Override
public void onDestroy(){
super.onDestroy();
}
}
I just want to know how to launch an Activity in a try/catch bloc, i made this
public void onReceive(Context context, Intent intent) {
SipAudioCall incomingCall = null;
try {
Intent monIntent = new Intent(this,dialog.class);
startActivity(monIntent);
SipAudioCall.Listener listener = new SipAudioCall.Listener() {
#Override
public void onRinging(SipAudioCall call, SipProfile caller) {
But i have errors:
constructor Intent(IncomingCallReceiver, Class<dialog>) is not defined
Method startActivity(Intent) is undefined for the type IncomingCallReceiver
I want to show an alertdialog when having a call.
How can i solve this problem?
Thank you very much.
Whole class:
public class IncomingCallReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
SipAudioCall incomingCall = null;
try {
SipAudioCall.Listener listener = new SipAudioCall.Listener() {
#Override
public void onRinging(SipAudioCall call, SipProfile caller) {
try {
call.answerCall(30);
} catch (Exception e) {
e.printStackTrace();
}
}
};
SIPCommunicator wtActivity = (SIPCommunicator) context;
incomingCall = wtActivity.manager.takeAudioCall(intent, listener);
incomingCall.answerCall(30);
incomingCall.startAudio();
incomingCall.setSpeakerMode(true);
if(incomingCall.isMuted()) {
incomingCall.toggleMute();
}
wtActivity.call = incomingCall;
wtActivity.updateStatus(incomingCall);
} catch (Exception e) {
if (incomingCall != null) {
incomingCall.close();
}
}
}
}
The problem you are facing is not the try catch block, it's the fact that you are starting activity in a listener implementation. Substitute
Intent monIntent = new Intent(this,dialog.class);
with
Intent monIntent = new Intent(<Name of this class>.this,dialog.class);
and
startActivity(monIntent);
with
<Name of this class>.this.startActivity(monIntent);
By <Name of this class> I mean the head class where you are writing your code.
By the looks of it, you are launching a new thread from within a try/catch block. This is bad practice as the thread can fail should an exception be being thrown.
Instead, declare a variable before the value, and assign to it on the line preceding the catch statement.
Also assign to it if the exception is raised, but a different value.
Then launch the thread outside the try/catch block, based on the successful evaluation of the variable.
Use callbacks to trap failed threads, not exceptions.
int x = 0;
try
{
/* Do some logic here */
x = 1; // we have success
}
catch(Exception e)
{
x = -1; // failure
}
if (x > 0)
{
Intent monIntent = new Intent(this,dialog.class);
startActivity(monIntent);
...
}
As a newbie I would like to state my view:-
Try putting some error messages to find out where the error is occurring. Also check the log file.
Example of try catch:-
try
{
//some code
//Toast message on success
Toast.makeText(this, R.string.msgStatusUpdatedSuccefully, Toast.LENGTH_LONG).show();
}
catch (TwitterException e)
{
//Toast message on failure
Toast.makeText(this, R.string.msgStatusUpdateFailed, Toast.LENGTH_LONG).show();
e.printStackTrace();
}
I would check if my imports are all fine for all the api's that I am using.
Also does your main public class looks like the following to resolve the undefined error:-
public class StatusActivity extends Activity implements OnClickListener{}