How to get Android Application to push notifications after ui thread is closed - android-asynctask

How to get push notification working after manually closing UI on Android?
Hi, I need some help, Couldn't find any solutions by searching.
Application basically is like any other messaging applications, ex. Whatsapp.
I have MessageService running as own process, even UI closed, it stays alive.
This is how my application basically works:
MainActivity start service
MessageService send broadCast to
messageReceiver gets broadCast and run messageLoader
MessagesLoader extends AsyncTask gets changes from database
MessagesLoader push notification.
Every these parts working correctly when UI running
When I close UI, messageService restarts again, but no push notifications after UI closed.
Any help to get this work would be appreciated.
Thanks
Here is some code snippet to understand how my thing works..
MainActivity.java
...........................
#Override
protected void onResume() {
super.onResume();
serviceIntent = new Intent(getApplicationContext(), MessageService.class);
startService(serviceIntent);
registerReceiver(messageReceiver, new IntentFilter(MessageService.MESSAGES_BROADCAST_ACTION));
}
...........................
MessageService.java
public class MessageService extends Service {
Updater updater;
BroadcastReceiver messageBroadcaster;
Intent intent;
Context context;
static final public String MESSAGES_BROADCAST_ACTION = "com.<Your Package>";
public MessageService() {
}
#Override
public IBinder onBind(Intent intent) {
this.intent = intent;
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public void onCreate() {
super.onCreate();
this.updater = new Updater();
this.context = getApplicationContext();
this.intent = new Intent(this, NotificationActivity.class);
Toast.makeText(this, "Message Service Created", Toast.LENGTH_LONG).show();
}
#Override
public synchronized int onStartCommand(Intent intent, int flags, int startId) {
if (!updater.isRunning()) {
updater.start();
updater.isRunning = true;
}
return super.onStartCommand(intent, flags, startId);
}
#Override
public synchronized void onDestroy() {
super.onDestroy();
if (updater.isRunning) {
updater.interrupt();
updater.isRunning = false;
updater = null;
}
Toast.makeText(this, "Message Service Destroyed", Toast.LENGTH_LONG).show();
}
class Updater extends Thread {
public boolean isRunning = false;
public long DELAY = 2500;
#Override
public void run() {
super.run();
isRunning = true;
while (isRunning) {
sendResult();
try {
Thread.sleep(DELAY);
} catch (InterruptedException e) {
e.printStackTrace();
isRunning = false;
}
}
}
public boolean isRunning() {
return this.isRunning;
}
}
public void sendResult() {
sendBroadcast(intent);
}
}
MessageReceiver.java
public class MessageReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
Intent serviceIntent = new Intent(context, MessageService.class);
context.startService(serviceIntent);
new MessagesLoader(context).execute();
}
}
MessageLoader.java
public class MessagesLoader extends AsyncTask<String,Void,String> {
public MessagesLoader(Context context) {
this.context = context;
this.intent = new Intent(this.context, ChatsActivity.class);
this.prev_count = prev_count;
Intent intent = new Intent(context, ChatsActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(context, 0, intent, 0);
this.mBuilder = new android.support.v4.app.NotificationCompat.Builder(context)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("YOUR APP");
}
protected void onPreExecute(){
}
#Override
protected String doInBackground(String... arg0) {
StringBuffer result = new StringBuffer("");
try {
URL url = new URL("http://yourURL.com/get_data.php");
HttpURLConnection con = (HttpURLConnection)url.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("User-Agent", "");
con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
con.setDoOutput(true);
String urlParameters = "<OWN PARAMETERS>";
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.writeBytes(urlParameters);
wr.flush();
wr.close();
int responseCode = con.getResponseCode();
con.connect();
InputStream inputStream = con.getInputStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(inputStream));
String line = "";
while ((line = rd.readLine()) != null) {
result.append(line);
}
return new String(result);
} catch(Exception e){
return new String("Exception: " + e.getMessage());
}
}
#Override
protected void onPostExecute(String result) {
initData(result);
}
public void initData(String result) {
// Actually Store Data to sharedPreferences
String error = "";
JSONObject obj = new JSONObject();
// ...ETC
int count = 5;
showNotification(5);
}
public void showNotification(int count) {
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Intent mIntent = new Intent(this.context, ChatsActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(this.context, 0, mIntent, 0);
Intent cIntent = new Intent(this.context, NotificationActionService.class);
PendingIntent cPIntent = PendingIntent.getService(this.context, 0, cIntent, 0);
NotificationCompat.BigTextStyle bigTextStyle = new NotificationCompat.BigTextStyle();
bigTextStyle.bigText("YOUR BIG TEXT");
Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
mBuilder
.setContentIntent(pIntent)
.setContentText("YOUR CONTENT TEXT")
.setAutoCancel(true)
.setLights(R.color.white, 1000, 500)
.setSound(soundUri)
.setGroup("YOUR GROUP")
.setTicker("YOUR TICKER TEXT")
.setWhen(System.currentTimeMillis())
.setCategory("YOUR CATEGORY")
.setStyle(bigTextStyle)
.addAction(0, "Show Messages", pIntent);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addParentStack(MainActivity.class);
stackBuilder.addNextIntent(mIntent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(resultPendingIntent);
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.yourpackage" >
android:versionCode="1"
android:versionName="1.0"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-feature android:name="android.hardware.camera" android:required="true" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:configChanges="orientation"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.yourpackage.MainActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
</intent-filter>
</activity>
<service android:name="com.yourpackage.MessageService"
android:process=":messageService"
android:enabled="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/messageService">
<intent-filter>
<action android:name="com.yourpackage.MessageService" />
</intent-filter>
</service>
<receiver android:name="com.yourpackage.MessageReceiver">
<intent-filter>
<action android:name="com.yourpackage.MessageReceiver" />
</intent-filter>
</receiver>
</application>
</manifest>

I've found the solution. Now my application is always showing me new messages info even without UI running.
Here is solution to fix this problem.
MainActivity.java
#Override
protected void onResume() {
super.onresume();
serviceIntent = new Intent(getApplicationContext(), MessageService.class);
startService(serviceIntent);
/* COMMENTED OUT LINE BELOW */
//registerReceiver(messageReceiver, new IntentFilter(MessageService.MESSAGES_BROADCAST_ACTION));
}
MessageService.java
#Override
public void onCreate() {
super.onCreate();
updater = new Updater();
context = getApplicationContext();
/* AND ADDED THAT LINE HERE AND */
registerReceiver(messageReceiver, new IntentFilter(MESSAGES_BROADCAST_ACTION));
intent = new Intent(MESSAGES_BROADCAST_ACTION);
Toast.makeText(this, "Message Service Created", Toast.LENGTH_LONG).show();
}

Related

simplest way to show native ads appodeal

Anybody can show here how to simplest way to show native ads appodeal?
NativeAdViewAppWall = before content webview and NativeAdViewContentStream = after content webview.
Thank you.
simple way to show native ad :
xml file :
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="70sp"
android:id="#+id/native_holder"
></RelativeLayout>
in onCreate :
private List<NativeAd> nativeAds = new ArrayList<>();
Appodeal.setTesting(true);
Appodeal.setAutoCache(Appodeal.NATIVE, false);
Appodeal.initialize(this, "apikey", Appodeal.NATIVE , true);
setNaitivAD();
and use this method :
private void setNaitivAD(){
Appodeal.cache(this, Appodeal.NATIVE);
Appodeal.setNativeCallbacks(new NativeCallbacks() {
#Override
public void onNativeLoaded() {
Toast.makeText(MainActivity.this, "onNativeLoaded!", Toast.LENGTH_SHORT).show();
nativeAds = Appodeal.getNativeAds(1);
RelativeLayout holder = (RelativeLayout) findViewById(R.id.native_holder);
NativeAdViewAppWall nativeAdView = new NativeAdViewAppWall(MainActivity.this, nativeAds.get(0));
holder.addView(nativeAdView);
}
#Override
public void onNativeFailedToLoad() {
Toast.makeText(MainActivity.this, "onNativeFailedToLoad", Toast.LENGTH_SHORT).show();
}
#Override
public void onNativeShown(NativeAd nativeAd) {
Toast.makeText(MainActivity.this, "onNativeShown", Toast.LENGTH_SHORT).show();
}
#Override
public void onNativeShowFailed(NativeAd nativeAd) {
}
#Override
public void onNativeClicked(NativeAd nativeAd) {
Toast.makeText(MainActivity.this, "onNativeClicked", Toast.LENGTH_SHORT).show();
}
#Override
public void onNativeExpired() {
}
});
}

Unable to access response data out of VolleyRequest, attempted callbacks

I have tried using callback similar to my fragments and other people suggestion on callbacks, However I've had no luck i could be doing the callbacks wrong. The Toast inside the onResponse method of JsonArrayRequest returns an array size of 2. But i get 0 on the toast outside of the request. consignment.class implements parcelable
public class BackgroundTask{
String json_url;
Gson gson;
Type listType;
ProgressDialog pDialog;
ArrayList<Consignment> arrayList = new ArrayList<>();
AppController appController;
ConsAdapter adapter;
Context context;
public BackgroundTask(Context context){
this.context = context;
listType = new TypeToken<List<Consignment>>(){}.getType();
appController = AppController.getInstance();
gson = new Gson();
}
public void getAllCons(final GetAllConsListener callBack) {
String tag_json_obj = "json_obj_req";
//showProgressDialog();
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.GET, json_url,null,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
callBack.onSuccess(response.toString());
//hideProgressDialog();
Toast.makeText(context, "Consignments:"+arrayList.size(), Toast.LENGTH_LONG).show();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
//Toast.makeText(context, "Error...", Toast.LENGTH_SHORT).show();
error.printStackTrace();
//hideProgressDialog();
}
});
appController.addToRequestQueue(jsonArrayRequest);
}
Activity Class:
public class GetConsActivity extends AppCompatActivity {
RecyclerView recyclerView;
ConsAdapter adapter;
RecyclerView.LayoutManager layoutManager;
ArrayList<Consignment> arrayList;
TextView txtView;
BackgroundTask backgroundTask;
Type listType;
Gson gson;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_get_cons);
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setHasFixedSize(true);
gson = new Gson();
listType = new TypeToken<ArrayList<Consignment>>(){}.getType();
BackgroundTask backgroundTask = new BackgroundTask(GetConsActivity.this);
backgroundTask.getAllCons(new GetAllConsListener() {
#Override
public void onSuccess(String response) {
ArrayList<Consignment> list = parseResponse(response);
updateUI(list);
//Toast.makeText(GetConsActivity.this, "Consignments:"+arrayList.size(), Toast.LENGTH_LONG).show();
Log.d("ONSUCCESS", "ARRAYSIZE: "+arrayList.size());
}
});
}
public ArrayList<Consignment> parseResponse(String response){
ArrayList<Consignment> list = new ArrayList<>();
try {
JSONArray jsonArray = new JSONArray(response);
Log.d("PARSE", "parseResponse: "+jsonArray.length());
JSONObject jsonObject = jsonArray.getJSONObject(0);
for (int i = 0; i<jsonArray.length();i++){
Consignment con = null;
Log.d("PARSE", "parseID: "+jsonObject.getInt("conid"));
con.setConid(jsonObject.getInt("conid"));
Log.d("PARSE", "conID: "+con.getConid());
con.setDescription(jsonObject.getString("description"));
list.add(con);
}
Log.d("PARSED", "parsedResponse: "+list.size());
} catch (JSONException e) {
e.printStackTrace();
}
//arrayList =gson.fromJson(response,new TypeToken<ArrayList<Consignment>>(){}.getType());
//updateUI(arrayList);
return list;
}
public void updateUI(ArrayList<Consignment> consignments){
this.arrayList = consignments;
Log.d("UPDATE", "parseResponse: "+consignments.size());
if (adapter == null) {
adapter = new ConsAdapter(consignments,GetConsActivity.this);
recyclerView.setAdapter(adapter);
}else{
adapter.setConsignments(consignments);
adapter.notifyDataSetChanged();
}
}
Error:
D/mali_winsys: EGLint new_window_surface(egl_winsys_display*, void*, EGLSurface, EGLConfig, egl_winsys_surface**, egl_color_buffer_format*, EGLBoolean) returns 0x3000, [1440x2560]-format:1
E/RecyclerView: No adapter attached; skipping layout
I/qtaguid: Untagging socket 51
D/ViewRootImpl: MSG_RESIZED_REPORT: ci=Rect(0, 84 - 0, 0) vi=Rect(0, 84 - 0, 0) or=1
E/RecyclerView: No adapter attached; skipping layout
D/PARSE: parseResponse: 4
D/PARSE: parseID: 123456789
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.angel.createcon, PID: 26952
java.lang.NullPointerException: Attempt to invoke virtual method 'void com.angel.createcon.Consignment.setConid(int)' on a null object reference
at com.angel.createcon.GetConsActivity.parseResponse(GetConsActivity.java:80)
at com.angel.createcon.GetConsActivity$2.onSuccess(GetConsActivity.java:56)
at com.angel.createcon.BackgroundTask$2.onResponse(BackgroundTask.java:50)
at com.angel.createcon.BackgroundTask$2.onResponse(BackgroundTask.java:47)
at com.android.volley.toolbox.JsonRequest.deliverResponse(JsonRequest.java:65)
at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:99)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:7331)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
I/Process: Sending signal. PID: 26952 SIG: 9
Application terminated.
So I'll take a stab at this - having the activity implement the listener that way is a bit strange, though I don't think that's the issue. I also don't understand why you chose to save the list type to a variable - I've not seen anyone do that before.
However, getting to your question about the toast and why it's 0 - If you're talking about the toast that comes after the getAllCons call -it's because that code is executed before the callback code. completes.
Try something like this and see what it does.
public class BackgroundTask{
String json_url;
Gson gson;
Type listType;
Context context;
public BackgroundTask(Context context){
this.context = context;
listType = new TypeToken<List<Consignment>>(){}.getType();
appController = AppController.getInstance();
gson = new Gson();
}
public void getAllCons(final GetAllConsListener callBack) {
String tag_json_obj = "json_obj_req";
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.GET, json_url,null,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
callBack.onSuccess(response.toString());
Toast.makeText(context, "Consignments:"+arrayList.size(), Toast.LENGTH_LONG).show();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
appController.addToRequestQueue(jsonArrayRequest);
}
public class GetConsActivity extends AppCompatActivity {
RecyclerView recyclerView;
ConsAdapter adapter;
RecyclerView.LayoutManager layoutManager;
TextView txtView;
BackgroundTask backgroundTask;
Gson gson;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_get_cons);
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setHasFixedSize(true);
gson = new Gson();
BackgroundTask backgroundTask = new BackgroundTask(GetConsActivity.this);
backgroundTask.getAllCons(new GetAllConsListener() {
#Override
public void onSuccess(String response) {
List<Consignment> values = parseResponse(response);
updateUI(values);
}
});
//code may execute here but callback is not yet complete.
}
public List<Consignment> parseResponse(String response){
return gson.fromJson(response,listType);
}
private void updateUI(List<Consignment> consignments){
if(adapter == null){
adapter = new ConsAdapter(consignments)
recyclerView.setAdapter(adapter);
} else {
adapter.consignments = consignments;
adapter.notifyDataSetChanged();
}
}

Wearable.MessageApi.sendMessage returning Success but onMessageReceived is not calling

Working on Wear application, I have created Wear application with Mobile and wear applications. Sending data from mobile application, through "MessageApi.SendMessageResult" and returning status is SUCCESS but message is not received in wear application. Please find the code in below and let me know i am missing any thing.
Mobile App Code:
public class MainActivity extends Activity implements GoogleApiClient.ConnectionCallbacks {
private static final String START_ACTIVITY = "/start_activity";
private static final String WEAR_MESSAGE_PATH = "/message";
private GoogleApiClient mApiClient;
private ArrayAdapter<String> mAdapter;
private ListView mListView;
private EditText mEditText;
private Button mSendButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
initGoogleApiClient();
}
private void initGoogleApiClient() {
mApiClient = new GoogleApiClient.Builder( this )
.addApi( Wearable.API )
.build();
mApiClient.connect();
}
#Override
protected void onDestroy() {
super.onDestroy();
mApiClient.disconnect();
}
private void init() {
mListView = (ListView) findViewById( R.id.list_view );
mEditText = (EditText) findViewById( R.id.input );
mSendButton = (Button) findViewById( R.id.btn_send );
mAdapter = new ArrayAdapter<String>( this, android.R.layout.simple_list_item_1 );
mListView.setAdapter( mAdapter );
mSendButton.setOnClickListener( new View.OnClickListener() {
#Override
public void onClick(View view) {
String text = mEditText.getText().toString();
if (!TextUtils.isEmpty(text)) {
mAdapter.add(text);
mAdapter.notifyDataSetChanged();
sendMessage(WEAR_MESSAGE_PATH, text);
}
}
});
}
private void sendMessage( final String path, final String text ) {
new Thread( new Runnable() {
#Override
public void run() {
//Previous code
NodeApi.GetConnectedNodesResult nodes = Wearable.NodeApi.getConnectedNodes( mApiClient ).await();
Log.d("MessageAPI","nodes :: "+nodes);
for(com.google.android.gms.wearable.Node node : nodes.getNodes()) {
Log.d("MessageAPI","nodes for :: "+node);
MessageApi.SendMessageResult result = Wearable.MessageApi.sendMessage(
mApiClient, node.getId(), path, text.getBytes() ).await();
Log.d("MessageAPI","node.getId() : "+node.getId());
Log.d("MessageAPI","text.getBytes() : "+text.getBytes());
Log.d("MessageAPI","path : "+path);
Log.d("MessageAPI","nodes result Status:: "+result.getStatus().isSuccess());
}
/*PutDataMapRequest putDMR = PutDataMapRequest.create(path);
putDMR.getDataMap().putAll(getDatMap());
PutDataRequest request = putDMR.asPutDataRequest();
DataApi.DataItemResult result = Wearable.DataApi.putDataItem(mApiClient, request).await();
if (result.getStatus().isSuccess()) {
Log.v("MessageAPI", "nodes DataMap: " + getDatMap() + " sent successfully to data layer ");
} else {
// Log an error
Log.v("MessageAPI", "nodes ERROR: failed to send DataMap to data layer");
}*/
runOnUiThread( new Runnable() {
#Override
public void run() {
mEditText.setText( "" );
}
});
}
}).start();
}
#Override
public void onConnected(Bundle bundle) {
sendMessage(START_ACTIVITY, "Wear my TEST MESSAGE");
}
#Override
public void onConnectionSuspended(int i) {
}
private DataMap getDatMap(){
DataMap dataMap = new DataMap();
dataMap.putLong("time", new Date().getTime());
dataMap.putString("hole", "1");
dataMap.putString("front", "250");
dataMap.putString("middle", "260");
dataMap.putString("back", "270");
return dataMap;
}
}
Mobile App manifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ptrprograms.wearmessageapi" >
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<meta-data android:name="com.google.android.gms.version" android:value="#integer/google_play_services_version" />
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
wearApp Code
public class WearMessageListenerService extends WearableListenerService {
private static final String START_ACTIVITY = "/start_activity";
#Override
public void onMessageReceived(MessageEvent messageEvent) {
Log.d("MessageAPI","onMessageReceived :: "+ messageEvent.getPath());
/* if( messageEvent.getPath().equalsIgnoreCase( START_ACTIVITY ) ) {
Intent intent = new Intent( this, MainActivity.class );
intent.addFlags( Intent.FLAG_ACTIVITY_NEW_TASK );
startActivity( intent );
} else {
super.onMessageReceived(messageEvent);
}*/
showToast("onMessageReceived:: "+messageEvent.getPath());
Intent intent = new Intent( this, MainActivity.class );
intent.addFlags( Intent.FLAG_ACTIVITY_NEW_TASK );
startActivity( intent );
}
private void showToast(String message) {
Toast.makeText(this, message, Toast.LENGTH_LONG).show();
}
#Override
public void onDataChanged(DataEventBuffer dataEventBuffer) {
super.onDataChanged(dataEventBuffer);
Log.d("MessageAPI","onMessageReceived : onDataChanged: ");
}
}
wearApp manifest:
<?xml version="1.0" encoding="utf-8"?>
<uses-feature android:name="android.hardware.type.watch" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#android:style/Theme.DeviceDefault" >
<meta-data android:name="com.google.android.gms.version" android:value="#integer/google_play_services_version" />
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- <service android:name=".WearMessageListenerService">
<intent-filter>
<action android:name="com.google.android.gms.wearable.BIND_LISTENER" />
</intent-filter>
</service>-->
<service android:name=".WearMessageListenerService">
<action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED" />
<action android:name="com.google.android.gms.wearable.DATA_CHANGED" />
<data android:scheme="wear" android:host="*" android:pathPrefix="/prefix" />
<!--<data android:scheme="wear" android:host="*"
android:path="/start_activity" />-->
<!--<action android:name="com.google.android.gms.wearable.CAPABILITY_CHANGED" />
<action android:name="com.google.android.gms.wearable.CHANNEL_EVENT" />-->
<!-- <data android:scheme="wear" android:host="*" android:path="/start_activity" />-->
</service>
</application>
1) Problem is in wearApp in WearMessageListenerService. You don't call
super.onMessageReceived(messageEvent);
i.e you consume all messages. When you call super method you pass message to Wearable.MessageApi.addListener(...
2) I don't see in your wear app that you register MessageApi listener.
3) You mix MessageApi with Data Layer api.
4) In wear app in Main activity you need connect with google play services too. To register MessageApi listener in onConnected method.
5) Please check https://github.com/mariopce/android-wear-bilateral-communication.
This is example of using MessageApi for 2-way communication (mobile-wear-mobile)

WearableListenerService doesn't receive data

I'm trying to send sensor data from my wear device to the handheld. The problem is that the onMessageReceived function of my WearableListenerService is never called, even though it gets created.
The package names of the wear and mobile apps are the same, also here's the entry for the service in the manifest file:
<service
android:name=".WatchDataReceiver"
android:enabled="true"
android:exported="true" >
</service>
On my handheld in the MainActivity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
startService(new Intent(this, WatchDataReceiver.class));
setContentView(R.layout.activity_fullscreen);
...
}
On my handheld, the service:
public class WatchDataReceiver extends WearableListenerService {
#Override
public void onCreate() {
super.onCreate();
Log.i(WatchDataReceiver.class.getSimpleName(), "WEAR create");
}
#Override
public void onDataChanged(DataEventBuffer dataEvents) {
Log.i(WatchDataReceiver.class.getSimpleName(), "WEAR Data changed " );
}
#Override
public void onMessageReceived(MessageEvent messageEvent) {
Log.i(WatchDataReceiver.class.getSimpleName(), "WEAR Message " + messageEvent.getPath());
}
}
On the watch/wear:
public class MainActivity extends Activity implements SensorEventListener {
private static final String LOG_TAG = "Watch: ";
private SensorManager sensorManager;
private Sensor accelerometer;
private GoogleApiClient mGoogleApiClient;
private String msg = "";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
#Override
public void onLayoutInflated(WatchViewStub stub) {
mTextView = (TextView) stub.findViewById(R.id.text);
}
});
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
sensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_FASTEST);
if (accelerometer != null) {
Log.v(LOG_TAG, "Accelerometer registered!");
}
else {
Log.v(LOG_TAG, "Accelerometer _not_ registered!");
}
mGoogleApiClient = new GoogleApiClient.Builder(this).addApi(Wearable.API).build();
mGoogleApiClient.connect();
}
#Override
public void onSensorChanged(SensorEvent event) {
if(event.sensor.getType() == Sensor.TYPE_ACCELEROMETER && event.values.length > 0) {
double value_x = event.values[0];
double value_y = event.values[1];
double value_z = event.values[2];
msg = Double.toString(value_x) + ";" + Double.toString(value_y) + ";" + Double.toString(value_z);
sendMessageToHandheld(msg);
}
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
//TODO
}
private void sendMessageToHandheld(String msg) {
if (mGoogleApiClient == null)
return;
final String message = msg;
Log.d(LOG_TAG,"sending a message to handheld: "+message);
// use the api client to send the heartbeat value to our handheld
final PendingResult<NodeApi.GetConnectedNodesResult> nodes = Wearable.NodeApi.getConnectedNodes(mGoogleApiClient);
nodes.setResultCallback(new ResultCallback<NodeApi.GetConnectedNodesResult>() {
#Override
public void onResult(NodeApi.GetConnectedNodesResult result) {
final List<Node> nodes = result.getNodes();
if (nodes != null) {
for (int i=0; i<nodes.size(); i++) {
final Node node = nodes.get(i);
Wearable.MessageApi.sendMessage(mGoogleApiClient, node.getId(), message, null);
}
}
}
});
}
}
According to LogCat the correct handheld is found because in sendMessageToHandheld right after the actual sendMessage it do a Log.d with the name of the node.
What am I missing?
You have to add this IntentFilter to your service:
<intent-filter>
<action android:name="com.google.android.gms.wearable.BIND_LISTENER" />
</intent-filter>
It tells the system to take care of the Service lifecycle (ie starting it if needed).

Volley library throws application exception

I am adding my two separate android activities in one application, one of my activity having volley library but it gives me an exception that appcontroller(volley library) its an application not an activity please help me out
Ya, you have mention in your manifest file appcontroller class as Application. This solves the exception.
Main Acitivity:
public class MainActivity extends FragmentActivity implements OnTabChangeListener, OnPageChangeListener {
MyPageAdapter pageAdapter;
private ViewPager mViewPager;
private TabHost mTabHost;
private Button btn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mViewPager = (ViewPager) findViewById(R.id.viewpager);
// Tab Initialization
initialiseTabHost();
// Fragments and ViewPager Initialization
List<Fragment> fragments = getFragments();
pageAdapter = new MyPageAdapter(getSupportFragmentManager(), fragments);
mViewPager.setAdapter(pageAdapter);
mViewPager.setOnPageChangeListener(MainActivity.this);
}
// Method to add a TabHost
private static void AddTab(MainActivity activity, TabHost tabHost, TabHost.TabSpec tabSpec,String message,int picture,Context x)
{
tabSpec.setContent(new MyTabFactory(activity));
View tabIndicator = LayoutInflater.from(x).inflate(R.layout.tab_indicator, tabHost.getTabWidget(), false);
TextView title = (TextView) tabIndicator.findViewById(R.id.title);
title.setText(message);
ImageView icon = (ImageView) tabIndicator.findViewById(R.id.icon);
icon.setBackgroundDrawable(x.getResources().getDrawable(picture));
icon.setScaleType(ImageView.ScaleType.FIT_CENTER);
tabSpec.setIndicator(tabIndicator);
tabHost.addTab(tabSpec);
}
// Manages the Tab changes, synchronizing it with Pages
public void onTabChanged(String tag) {
int pos = this.mTabHost.getCurrentTab();
this.mViewPager.setCurrentItem(pos);
for(int i=0;i<mTabHost.getTabWidget().getChildCount();i++)
{
mTabHost.getTabWidget().getChildAt(i).setBackgroundColor(Color.BLUE);
//mTabHost.getTabWidget().setDividerDrawable(R.Color.transperant);
}
mTabHost.getTabWidget().getChildAt(mTabHost.getCurrentTab()).setBackgroundColor(Color.CYAN);// selected
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
public void destroyItem(View collection, int position, Object view){
((ViewPager) collection).removeView((ImageView) view);
}
// Manages the Page changes, synchronizing it with Tabs
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
int pos = this.mViewPager.getCurrentItem();
this.mTabHost.setCurrentTab(pos);
}
#Override
public void onPageSelected(int arg0) {
}
private List<Fragment> getFragments(){
List<Fragment> fList = new ArrayList<Fragment>();
// TODO Put here your Fragments
NewSampleFragment f1 = NewSampleFragment.newInstance(getApplicationContext(),R.layout.newfragment_a);
MySampleFragment f2 = MySampleFragment.newInstance("Sample Fragment 2");
MySampleFragment f3 = MySampleFragment.newInstance("Sample Fragment 3");
MySampleFragment f4 = MySampleFragment.newInstance("Sample Fragment 4");
MySampleFragment f5 = MySampleFragment.newInstance("Sample Fragment 5");
fList.add(f1);
fList.add(f2);
fList.add(f3);
fList.add(f4);
fList.add(f5);
return fList;
}
// Tabs Creation
private void initialiseTabHost() {
mTabHost = (TabHost) findViewById(android.R.id.tabhost);
mTabHost.setup();
// TODO Put here your Tabs
MainActivity.AddTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab1").setIndicator("Tab1"),"Grocery",R.drawable.movies,getApplicationContext());
MainActivity.AddTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab2").setIndicator("Tab2"),"Crockery",R.drawable.artist,getApplicationContext());
MainActivity.AddTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab3").setIndicator("Tab3"),"Foods",R.drawable.song,getApplicationContext());
MainActivity.AddTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab3").setIndicator("Tab4"),"Drinks",R.drawable.shopping,getApplicationContext());
MainActivity.AddTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab3").setIndicator("Tab5"),"Toys",R.drawable.play,getApplicationContext());
mTabHost.setOnTabChangedListener(this);
}
}
OfferActivity (This should be open when button pressed)
public class OfferActivity extends Activity
{
private static final String TAG = MainActivity.class.getSimpleName();
private ListView listView;
private FeedListAdapter listAdapter;
private List<FeedItem> feedItems;
private ProgressDialog pDialog;
private String URL_FEED = "http://nusdtech.com/public_html/checking2.php";
#SuppressLint("NewApi")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main1);
listView = (ListView) findViewById(R.id.list);
feedItems = new ArrayList<FeedItem>();
listAdapter = new FeedListAdapter(this, feedItems);
listView.setAdapter(listAdapter);
pDialog = new ProgressDialog(this);
// Showing progress dialog before making http request
pDialog.setMessage("Loading...");
pDialog.show();
// These two lines not needed,
// just to get the look of facebook (changing background color & hiding the icon)
getActionBar().setBackgroundDrawable(new ColorDrawable(Color.parseColor("#3b5998")));
//getActionBar().setIcon(
// new ColorDrawable(getResources().getColor(android.R.color.transparent)));
JsonArrayRequest movieReq = new JsonArrayRequest(URL_FEED,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
hidePDialog();
// Parsing json
for (int i = 0; i < response.length(); i++) {
try {
JSONObject obj = response.getJSONObject(i);
FeedItem movie = new FeedItem();
movie.setId(obj.getInt("id"));
movie.setName(obj.getString("name"));
// Image might be null sometimes
String image = obj.isNull("image") ? null : obj
.getString("image");
movie.setImge(image);
movie.setStatus(obj.getString("status"));
movie.setProfilePic(obj.getString("profilePic"));
//movie.setTimeStamp(obj.getString("price"));
movie.setPrice(obj.getString("price"));
movie.setDate(obj.getString("dates"));
feedItems.add(movie);
} catch (JSONException e) {
e.printStackTrace();
}
}
// notifying list adapter about data changes
// so that it renders the list view with updated data
listAdapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
hidePDialog();
}
});
// Adding request to request queue
AppController.getInstance().addToRequestQueue(movieReq);
}
#Override
public void onDestroy() {
super.onDestroy();
hidePDialog();
}
private void hidePDialog() {
if (pDialog != null) {
pDialog.dismiss();
pDialog = null;
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
AppController:
public class AppController extends Application {
public static final String TAG = AppController.class.getSimpleName();
private RequestQueue mRequestQueue;
private ImageLoader mImageLoader;
LruBitmapCache mLruBitmapCache;
private static AppController mInstance;
#Override
public void onCreate() {
super.onCreate();
mInstance = this;
}
public static synchronized AppController getInstance() {
return mInstance;
}
public RequestQueue getRequestQueue() {
if (mRequestQueue == null) {
mRequestQueue = Volley.newRequestQueue(getApplicationContext());
}
return mRequestQueue;
}
public ImageLoader getImageLoader() {
getRequestQueue();
if (mImageLoader == null) {
getLruBitmapCache();
mImageLoader = new ImageLoader(this.mRequestQueue, mLruBitmapCache);
}
return this.mImageLoader;
}
public LruBitmapCache getLruBitmapCache() {
if (mLruBitmapCache == null)
mLruBitmapCache = new LruBitmapCache();
return this.mLruBitmapCache;
}
public <T> void addToRequestQueue(Request<T> req, String tag) {
req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
getRequestQueue().add(req);
}
public <T> void addToRequestQueue(Request<T> req) {
req.setTag(TAG);
getRequestQueue().add(req);
}
public void cancelPendingRequests(Object tag) {
if (mRequestQueue != null) {
mRequestQueue.cancelAll(tag);
}
}
}
Activity that contain fragment buttons
public class NewSampleFragment extends Fragment {
private static View mView;
private Context con;
public static final NewSampleFragment newInstance(Context con,int layout) {
NewSampleFragment f = new NewSampleFragment();
con=con;
Bundle b = new Bundle();
b.putInt("mylayout",layout);
f.setArguments(b);
return f;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
int layout = getArguments().getInt("mylayout");
mView = inflater.inflate(R.layout.newfragment_a, container, false);
Button button = (Button) mView.findViewById(R.id.bactivity);
Button offer=(Button) mView.findViewById(R.id.aactivity);
button.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
Intent myIntent = new Intent(getActivity(), ListViewDemo.class);
//Optional parameters
getActivity().startActivity(myIntent);
Log.e("Error","Kashif");
}
});
offer.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
startApplication("uzair.sabir.app.OfferActivity");
}
});
return mView;
}
public void startApplication(String application_name){
try{
Intent intent = new Intent("android.intent.action.MAIN");
intent.addCategory("android.intent.category.LAUNCHER");
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
List<ResolveInfo> resolveinfo_list = getActivity().getPackageManager().queryIntentActivities(intent, 0);
for(ResolveInfo info:resolveinfo_list){
if(info.activityInfo.packageName.equalsIgnoreCase(application_name)){
launchComponent("uzair.sabir.app", "OfferActivity");
break;
}
}
}
catch (ActivityNotFoundException e) {
Toast.makeText(getActivity(), "There was a problem loading the application: "+application_name,Toast.LENGTH_SHORT).show();
Log.e("Error",e.getMessage());
}
}
private void launchComponent(String packageName, String name){
Intent launch_intent = new Intent("android.intent.action.MAIN");
launch_intent.addCategory("android.intent.category.LAUNCHER");
launch_intent.setComponent(new ComponentName(packageName, name));
launch_intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getActivity().startActivity(launch_intent);
}
}

Resources