I am going to write an application using google play services activity recognition api. the training in android developer site was straight forward but in the past couple of hours i wrote a simple application but i can't get any result from it.
UPDATE : Actually i am going to show the current activity of user in 5 second intervals as a toast message (as you can see in OnIntentHandler method in ActivityRecognitionService Intent Servie) . i think something is wrong with the calling the Intent because as you can see in my code the toast that says the ActivityRecognitionClient is connected on OnConnected method.
did i miss something ?
Thanks in advance.
Manifest File :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.nikapps.activityrecognition"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<uses-permission
android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION"/>
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<service
android:name="com.nikapps.activityrecognition.ActivityRecognitionService"
android:label="#string/app_name"
android:exported="false">
</service>
<activity
android:name="com.nikapps.activityrecognition.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>
</manifest>
MainActivity.java
package com.nikapps.activityrecognition;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks;
import com.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener;
import com.google.android.gms.location.ActivityRecognitionClient;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.Menu;
import android.widget.Toast;
public class MainActivity extends FragmentActivity implements ConnectionCallbacks, OnConnectionFailedListener{
public static int intervals = 5000;
private PendingIntent pendingIntent;
private ActivityRecognitionClient activityRecognition;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
activityRecognition = new ActivityRecognitionClient(this, this, this);
activityRecognition.connect();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public void onConnectionFailed(ConnectionResult result) {
// TODO Auto-generated method stub
}
#Override
public void onConnected(Bundle connectionHint) {
// TODO Auto-generated method stub
Toast.makeText(this, "connected", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(this, ActivityRecognitionService.class);
pendingIntent = PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
activityRecognition.requestActivityUpdates(0, pendingIntent);
}
#Override
public void onDisconnected() {
// TODO Auto-generated method stub
Toast.makeText(this, "disconnected", Toast.LENGTH_SHORT).show();
}
}
ActivityRecognitionService.java
package com.nikapps.activityrecognition;
import com.google.android.gms.location.ActivityRecognitionResult;
import com.google.android.gms.location.DetectedActivity;
import android.app.IntentService;
import android.content.Intent;
import android.widget.Toast;
public class ActivityRecognitionService extends IntentService{
public ActivityRecognitionService() {
super("ActivityRecognitionService");
Toast.makeText(this, "here", Toast.LENGTH_SHORT).show();
// TODO Auto-generated constructor stub
}
#Override
protected void onHandleIntent(Intent intent) {
// TODO Auto-generated method stub
Toast.makeText(this, "here2", Toast.LENGTH_SHORT).show();
ActivityRecognitionResult result = ActivityRecognitionResult.extractResult(intent);
DetectedActivity activity = result.getMostProbableActivity();
int type = activity.getType();
Toast.makeText(this, getNameFromType(type), Toast.LENGTH_SHORT).show();
}
private String getNameFromType(int activityType) {
switch(activityType) {
case DetectedActivity.IN_VEHICLE:
return "in_vehicle";
case DetectedActivity.ON_BICYCLE:
return "on_bicycle";
case DetectedActivity.ON_FOOT:
return "on_foot";
case DetectedActivity.STILL:
return "still";
case DetectedActivity.UNKNOWN:
return "unknown";
case DetectedActivity.TILTING:
return "tilting";
}
return "unknown";
}
}
You can broadcast an intent to send messages from the service to the main class
For example, use the following in your ActivityRecognitionService.java:
Intent mIntent = new Intent("myCustomIntentMessage")
.putExtra("ActivityType", getNameFromType(type));
getLocalBroadcast().sendBroadcast(mIntent);
Then you just need to register the broadcast receiver for "myCustomIntentMessage" on your MainActivity.java and put the Toast message code in the broadcast receiver OnReceive event.
You can only call the Toast from a thread that has a handler/Looper set up. To achieve what you're envisioning you have two options
Use a broadcast from the IntentService and have an activity that has a BroadcastReceiver that shows the UI. This way, the toast is not shown when the activity is not in the foreground . register/unregister the receiver in your onResume()/onPause()
create a handler and call your method in Handler.post(new Runnable() {.. })
Error calling toast from Service Android
Related
I'm using the following code for MediaPlayer services. But the following service is not running. The toasts are being triggered but the player doesn't play any song.
The 'onStart()' method is deprecated as I override it.
package com.example.user.stringremoval;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.widget.Toast;
public class MyService extends Service {
MediaPlayer mediaPlayer;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate()
{
Toast.makeText(this, "Service Created", Toast.LENGTH_SHORT).show();
mediaPlayer=MediaPlayer.create(this,R.raw.bet);
mediaPlayer.setVolume(50,50);
mediaPlayer.setLooping(false);
}
#Override
public void onStart(Intent intent,int startId)
{
Toast.makeText(this, "Service Started", Toast.LENGTH_SHORT).show();
mediaPlayer.start();
}
#Override
public void onDestroy()
{
Toast.makeText(this, "Service Destroyed", Toast.LENGTH_SHORT).show();
mediaPlayer.stop();
}
}
Error in Logcat:
06-27 12:47:03.175 3022-3022/com.example.user.stringremoval E/MediaPlayer-JNI: JNIMediaPlayerFactory: bIsQCMediaPlayerPresent 0
JNIMediaPlayerFactory: bIsQCMediaPlayerPresent 0
Activity class:
package com.example.user.stringremoval;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class AudioPlayer extends AppCompatActivity implements View.OnClickListener {
Button bn1,bn2,bn3;
Intent intent1=getIntent();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_audio_player);
bn1=(Button)findViewById(R.id.button3);
bn2=(Button)findViewById(R.id.button4);
bn3=(Button)findViewById(R.id.button5);
bn1.setOnClickListener(this);
bn2.setOnClickListener(this);
bn3.setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch (v.getId())
{
case R.id.button3:
startService(new Intent(this,MyService.class));
break;
case R.id.button4:
stopService(new Intent(this,MyService.class));
break;
case R.id.button5:
Intent intent=new Intent(this,MainActivity.class);
startActivity(intent);
}
}
}
Android Manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.user.stringremoval">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".AudioPlayer"></activity>
<service android:name=".MyService"
android:enabled="true"/>
</application>
</manifest>
Can anyone help me to resolve this problem?
You have to Override onStartCommand() method and return START_STICKY have look this!
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// play mp3 code here
return START_STICKY;
}
refer this link for better understanding of above method and START_STICKY.
Hope it will help you!
Try this code and define below things into your code..
// this line define into activity class into oncrateview method.
startService(new Intent(MyActivity.this, MyService.class));
add below line into android manifest file ..
between application tag..
<service android:enabled="true" android:name="com.my.packagename.MyService" />
I am trying to create sample application in android which could access the remote service already created in android.
Below are the code of my service, it's AIDL and sample application. Please note that I am trying to run it in android emulator.
My AIDL file
// IMyAidlInterface.aidl
package com.example.mmjoshi.binderservice;
// Declare any non-default types here with import statements
interface IMyAidlInterface {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
int findFactorialService(int x);
}
My Service file
package com.example.mmjoshi.binderservice;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
/**
* Created by mmjoshi on 8/12/2015.
*/
public class MyService extends Service {
private final IBinder mBinder = new LocalBinder();
#Override
public IBinder onBind(Intent intent)
{
//return mBinder;
return new IMyAidlInterface.Stub(){
public int findFactorialService(int x) throws RemoteException
{
int fact =1;
for(int i=1;i<=x;i++)
{
fact = fact*i;
}
return fact;
//return 5;
}
};
}
public class LocalBinder extends Binder
{
public MyService getService()
{
return MyService.this;
}
}
/*public int findFactorial(int x)
{
int fact =1;
for(int i=1;i<=x;i++)
{
fact = fact*i;
}
return fact;
//return 5;
}*/
}
Service Manifest file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.mmjoshi.binderservice" >
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<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=".MyService" android:process=":remote"
android:enabled="true" android:exported="true">
<intent-filter>
<action android:name="com.example.mmjoshi.binderservice.MyService.IMyAidlInterface"></action>
</intent-filter>
</service>
</application>
</manifest>
Another application which access this service
package secondndapp.service_client;
import android.app.Activity;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.example.mmjoshi.binderservice.IMyAidlInterface;
public class MainActivity extends Activity implements View.OnClickListener {
EditText etValue1, etValue2;
Button bAdd;
ServiceConnection AddServiceConnection;
protected IMyAidlInterface iMyAidlInterface;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
etValue1 = (EditText)findViewById(R.id.txtinput);
bAdd = (Button)findViewById(R.id.btnCalc);
bAdd.setOnClickListener(this);
initConnection();
}
void initConnection() {
AddServiceConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
iMyAidlInterface = IMyAidlInterface.Stub.asInterface((IBinder) service);
Toast.makeText(getApplicationContext(),
"Service Connected", Toast.LENGTH_SHORT)
.show();
Log.d("IRemote", "Binding is done - Service connected");
}
#Override
public void onServiceDisconnected(ComponentName name) {
iMyAidlInterface = null;
Toast.makeText(getApplicationContext(), "Service Disconnected",
Toast.LENGTH_SHORT).show();
Log.d("IRemote", "Binding - Service disconnected");
}
};
if (iMyAidlInterface == null) {
Intent it = new Intent("com.example.mmjoshi.binderservice.MyService");
it.setPackage("com.example.mmjoshi");
it.setAction("com.example.mmjoshi.binderservice.MyService.IMyAidlInterface");
it.setComponent(new ComponentName("com.example.mmjoshi", "com.example.mmjoshi.binderservice.MyService"));
// binding to remote service
startService(it);
Log.d("Service-MJ","Service is going to start");
bindService(it, AddServiceConnection, Service.BIND_AUTO_CREATE);
Log.d("Service-MJ", "Service is started");
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public void onClick(View v)
{
int num = Integer.parseInt(etValue1.getText().toString());
Toast.makeText(getApplicationContext(), "num is " + num,
Toast.LENGTH_LONG).show();
int result = 0;
try {
result = iMyAidlInterface.findFactorialService(num);
} catch (RemoteException e) {
e.printStackTrace();
}
Toast.makeText(getApplicationContext(), "Result" + result,Toast.LENGTH_SHORT).show();
}
}
Now, first I run the Binder Service in emulator and then I run this application in emulator.
But I am getting this error: "java.lang.NullPointerException: Attempt to invoke interface method 'int com.example.mmjoshi.binderservice.IMyAidlInterface.findFactorialService(int)' on a null object reference"
Please help me, I am stuck with this since last 2 days.
Thanks in Advance.
Maulik
I just created a service as shown below :
package com.example.timepass;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.os.Bundle;
import android.os.IBinder;
import android.widget.Toast;
public class alarm extends Service{
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
Toast.makeText(this, "Entered in service", Toast.LENGTH_SHORT).show();
}
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "onStartCommand...", Toast.LENGTH_LONG).show();
return 1;
// Log.i("YourService", "Yes this works.");
}
#Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, "Service destroyed...", Toast.LENGTH_LONG).show();
}
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
Toast.makeText(this, "Changed", Toast.LENGTH_SHORT).show();
return null;
}
}
Now when I startservice from mainactivity by the following command:
Intent myIntent = new Intent("com.example.timepass.ALARM");
MainActivity.this.startService(myIntent);
By doing this there is no error, but no TOAST of Service class are dipslayed
My manifest is :
<service class=".alarm" android:name=".alarm" android:enabled="true">
<intent-filter>
<action android:value="com.example.timepass.ALARM"
android:name=".alarm" />
</intent-filter>
</service>
Please guide me!!!
Probably you don't have the service in your manifest, or it does not have an that matches your action. Examining LogCat should turn up some warnings that may help.
More likely, you should start the service via:
startService(new Intent(this, alarm.class));
Here is my service class
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
public class Communicationservice extends Service {
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
super.onCreate();
Log.d("I AM Service","Service Created");
}
#Override
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
super.onStart(intent, startId);
}
}
Here is my Main Activity
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.util.Log;
import android.view.Menu;
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d("flow","1");
Intent in = new Intent("com.yal.Communication.Communicationservice");
this.startService(in);
//startService(new Intent(MainActivity.this,Communicationservice.class));
Log.d("flow","2");
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
Here is Mainfest.xml
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity > ... </activity>
<service android:enabled="true" android:name="com.yal.Communication.Communicationservice"></service>
</application>
Error
11-02 16:34:17.939: D/flow(1390): 1
11-02 16:34:17.939: W/ActivityManager(92): Unable to start service Intent { act=com.yal.Communication.Communicationservice }: not found
11-02 16:34:17.939: D/flow(1390): 2
you need to check Intent-Filter.
below snippet will help you.
<service android:name="com.yal.Communication.Communicationservice">
<intent-filter>
<action android:name="com.yal.Communication.Communicationservice" />
</intent-filter>
</service>
Then you can call this services like follows.
Intent serviceIntent = new Intent("com.yal.Communication.Communicationservice");
startService(serviceIntent);
Constructor public Intent (String action) can be used to specify action only see following java doc:
public Intent (String action)
Create an intent with a given action. All other fields (data, type, class) are null. Note that the action must be in a namespace because Intents are used globally in the system -- for example the system VIEW action is android.intent.action.VIEW; an application's custom action would be something like com.google.app.myapp.CUSTOM_ACTION.
Parameters
action The Intent action, such as ACTION_VIEW.
make following change to you intent creation:
Intent in = new Intent(this,com.yal.Communication.Communicationservice.class);
Or specify the action in the me manifest file:
<service android:name="com.yal.Communication.Communicationservice">
<intent-filter>
<action android:name="com.yal.Communication.Communicationservice" />
</intent-filter>
</service>
I have an Activity class, in which I have a static flag, let's say
public static volatile flag = false;
Then in the class, I start a thread, which checks the flag and do different things.
I also have a broadcastreceiver, which sets the flag to true or false.
I though volatile will force the flag to the most recent value. But I can see my broadcastreceiver sets the static flag to true, but my thread is still getting it as false.
Am I missing something basic here? Any help would be appreciated!
Simplified Code (Updated) - So the flag is supposed to change to true after one minute. But it never did. But message from broadcast receiver shows it has been change to true
TestappActivity.java:
package com.test;
import java.util.Calendar;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
public class TestappActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Intent intent0 = new Intent(this, TestService.class);
this.startService(intent0);
Intent intent = new Intent(this, TestReceiver.class);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
PendingIntent sender = PendingIntent.getBroadcast(this,
1, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
Calendar slot = Calendar.getInstance();
int min = slot.get(Calendar.MINUTE);
slot.set(Calendar.MINUTE, min+1);
am.set(AlarmManager.RTC_WAKEUP, slot.getTimeInMillis(), sender);
}
}
TestService.java:
package com.test;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
public class TestService extends Service {
private static final String TAG = "TestService";
public static volatile boolean flag = false;
private MyTopThread mTopThread;
public TestService() {
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
}
#Override
public void onDestroy() {
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
protect();
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
return START_STICKY;
}
/**
* Run protection
*
*/
private void protect() {
mTopThread = new MyTopThread();
mTopThread.start();
}
private class MyTopThread extends Thread {
#Override
public void run() {
while (true) {
try {
Thread.sleep(150);
Log.d(TAG, "Flag is " + TestService.flag);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
TestReceiver.java:
package com.test;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class TestReceiver extends BroadcastReceiver {
final static private String TAG = "TestReceiver";
#Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "onReceive is triggered ...");
TestService.flag = true;
Log.d(TAG, "flag is changed to " + TestService.flag);
}
}
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="8" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:name=".TestappActivity"
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=".TestService" />
<receiver
android:name=".TestReceiver"
android:process=":remote" >
</receiver>
</application>
</manifest>
I think the problem is that you are running the receiver in its own process. From the docs for the android:process attribute of <receiver>:
If the name assigned to this attribute begins with a colon (':'), a new process, private to the application, is created when it's needed and the broadcast receiver runs in that process.
I think the receiver is modifying a process-local version of TestService.flag, not the one being used by TestService. Try removing the android:process attribute from the <receiver> tag in your manifest.
From this link
http://www.javamex.com/tutorials/synchronization_volatile.shtml
Essentially, volatile is used to indicate that a variable's value will
be modified by different threads.
I really hope your service thread is not this one (I don't see any other one):
private class MyTopThread extends Thread {
#Override
public void run() {
while (true) {
try {
Thread.sleep(150);
Log.d(TAG, "Flag is " + TestService.flag);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Because you have while(true) here, not while(!flag) as it should be.