In my application i want to send push notifications using third party push woosh.I am using jar file.when i run application it is showing status of register and register id but if i push messages they are not displayed in phone.
public class MainActivity extends FragmentActivity implements SendTagsCallBack
{
private static final String SEND_TAGS_STATUS_FRAGMENT_TAG ="send_tags_status_fragment_tag";
private static final String APP_ID = "554B5-9B410";
private static final String SENDER_ID = "944240090087";
private TextView mTagsStatus;
private EditText mIntTags;
private EditText mStringTags;
private Button mSubmitTagsButton;
private TextView mGeneralStatus;
/**
* Called when the activity is first created.
*/
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//NetworkUtils.useSSL = true;
PushManager pushManager = new PushManager(this, APP_ID, SENDER_ID);
pushManager.onStartup(this);
mGeneralStatus = (TextView) findViewById(R.id.general_status);
mTagsStatus = (TextView) findViewById(R.id.status);
mIntTags = (EditText) findViewById(R.id.tag_int);
mStringTags = (EditText) findViewById(R.id.tag_string);
checkMessage(getIntent());
mSubmitTagsButton = (Button) findViewById(R.id.submit_tags);
mSubmitTagsButton.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
checkAndSendTagsIfWeCan();
}
});
SendTagsFragment sendTagsFragment = getSendTagsFragment();
mTagsStatus.setText(sendTagsFragment.getSendTagsStatus());
mSubmitTagsButton.setEnabled(sendTagsFragment.canSendTags());
}
/**
* Called when the activity receives a new intent.
*/
public void onNewIntent(Intent intent)
{
super.onNewIntent(intent);
checkMessage(intent);
}
#Override
public void onStatusChange(int sendTagsStatus)
{
mTagsStatus.setText(sendTagsStatus);
}
#Override
public void onTaskEnds()
{
mSubmitTagsButton.setEnabled(true);
}
#Override
public void onTaskStarts()
{
mSubmitTagsButton.setEnabled(false);
}
private void checkAndSendTagsIfWeCan()
{
SendTagsFragment sendTagsFragment = getSendTagsFragment();
if (sendTagsFragment.canSendTags())
{
sendTagsFragment
.submitTags(this, mIntTags.getText().toString().trim(), mStringTags.getText().toString().trim());
}
}
/**
* Will check PushWoosh extras in this intent, and fire actual method
*
* #param intent activity intent
*/
private void checkMessage(Intent intent)
{
if (null != intent)
{
if (intent.hasExtra(PushManager.PUSH_RECEIVE_EVENT))
{
doOnMessageReceive(intent.getExtras().getString(PushManager.PUSH_RECEIVE_EVENT));
}
else if (intent.hasExtra(PushManager.REGISTER_EVENT))
{
doOnRegistered(intent.getExtras().getString(PushManager.REGISTER_EVENT));
}
else if (intent.hasExtra(PushManager.UNREGISTER_EVENT))
{
doOnUnregisteredError(intent.getExtras().getString(PushManager.UNREGISTER_EVENT));
}
else if (intent.hasExtra(PushManager.REGISTER_ERROR_EVENT))
{
doOnRegisteredError(intent.getExtras().getString(PushManager.REGISTER_ERROR_EVENT));
}
else if (intent.hasExtra(PushManager.UNREGISTER_ERROR_EVENT))
{
doOnUnregistered(intent.getExtras().getString(PushManager.UNREGISTER_ERROR_EVENT));
}
resetIntentValues();
}
}
public void doOnRegistered(String registrationId)
{
mGeneralStatus.setText(getString(R.string.registered, registrationId));
}
public void doOnRegisteredError(String errorId)
{
mGeneralStatus.setText(getString(R.string.registered_error, errorId));
}
public void doOnUnregistered(String registrationId)
{
mGeneralStatus.setText(getString(R.string.unregistered, registrationId));
}
public void doOnUnregisteredError(String errorId)
{
mGeneralStatus.setText(getString(R.string.unregistered_error, errorId));
}
public void doOnMessageReceive(String message)
{
mGeneralStatus.setText(getString(R.string.on_message, message));
}
/**
* Will check main Activity intent and if it contains any PushWoosh data, will clear it
*/
private void resetIntentValues()
{
Intent mainAppIntent = getIntent();
if (mainAppIntent.hasExtra(PushManager.PUSH_RECEIVE_EVENT))
{
mainAppIntent.putExtra(PushManager.PUSH_RECEIVE_EVENT, (String) null);
}
else if (mainAppIntent.hasExtra(PushManager.REGISTER_EVENT))
{
mainAppIntent.putExtra(PushManager.REGISTER_EVENT, (String) null);
}
else if (mainAppIntent.hasExtra(PushManager.UNREGISTER_EVENT))
{
mainAppIntent.putExtra(PushManager.UNREGISTER_EVENT, (String) null);
}
else if (mainAppIntent.hasExtra(PushManager.REGISTER_ERROR_EVENT))
{
mainAppIntent.putExtra(PushManager.REGISTER_ERROR_EVENT, (String) null);
}
else if (mainAppIntent.hasExtra(PushManager.UNREGISTER_ERROR_EVENT))
{
mainAppIntent.putExtra(PushManager.UNREGISTER_ERROR_EVENT, (String) null);
}
setIntent(mainAppIntent);
}
private SendTagsFragment getSendTagsFragment()
{
FragmentManager fragmentManager = getSupportFragmentManager();
SendTagsFragment sendTagsFragment =
(SendTagsFragment) fragmentManager.findFragmentByTag(SEND_TAGS_STATUS_FRAGMENT_TAG);
if (null == sendTagsFragment)
{
sendTagsFragment = new SendTagsFragment();
sendTagsFragment.setRetainInstance(true);
fragmentManager.beginTransaction().add(sendTagsFragment, SEND_TAGS_STATUS_FRAGMENT_TAG).commit();
fragmentManager.executePendingTransactions();
}
return sendTagsFragment;
}
#Override
protected void onDestroy()
{
super.onDestroy();
mIntTags = null;
mStringTags = null;
mTagsStatus = null;
mSubmitTagsButton = null;
}
}
/*SendTagsFragment*/
public class SendTagsFragment extends Fragment implements SendPushTagsCallBack
{
private final Object mSyncObject = new Object();
private int mSendTagsStatus = R.string.status_ready;
private AsyncTask<Void, Void, Void> mTask;
public SendTagsFragment()
{
}
public boolean canSendTags()
{
synchronized (mSyncObject)
{
return mTask == null;
}
}
public void submitTags(final Context context, String tagInt, String tagString)
{
synchronized (mSyncObject)
{
if (!canSendTags())
{
return;
}
if (!goodAllInputData(tagInt, tagString))
{
return;
}
mSendTagsStatus = R.string.status_started;
transfareTaskStartsToActivity();
final Map<String, Object> tags = generateTags(tagInt, tagString);
mTask = new AsyncTask<Void, Void, Void>()
{
#Override
protected Void doInBackground(Void... params)
{
PushManager.sendTags(context, tags, SendTagsFragment.this);
return null;
}
};
mTask.execute((Void) null);
}
}
public int getSendTagsStatus()
{
synchronized (mSyncObject)
{
return mSendTagsStatus;
}
}
#Override
public void taskStarted()
{
synchronized (mSyncObject)
{
mSendTagsStatus = R.string.status_started;
transfareStatusToActivity();
}
}
#Override
public void onSentTagsSuccess(Map<String, String> stringStringMap)
{
synchronized (mSyncObject)
{
mSendTagsStatus = R.string.status_success;
mTask = null;
transfareStatusToActivity();
transfareTaskEndsToActivity();
}
}
#Override
public void onSentTagsError(PushWooshException e)
{
synchronized (mSyncObject)
{
mSendTagsStatus = R.string.status_error;
if (null != e)
{
e.printStackTrace();
}
mTask = null;
transfareStatusToActivity();
transfareTaskEndsToActivity();
}
}
private boolean goodAllInputData(String tagInt, String tagString)
{
if (tagInt.length() == 0 && tagString.length() == 0)
{
mSendTagsStatus = R.string.status_init_error;
transfareStatusToActivity();
transfareTaskEndsToActivity();
return false;
}
if (tagInt.length() != 0)
{
try
{
Integer.parseInt(tagInt);
}
catch (Exception e)
{
mSendTagsStatus = R.string.status_int_parse_error;
transfareStatusToActivity();
transfareTaskEndsToActivity();
return false;
}
}
return true;
}
private void transfareTaskStartsToActivity()
{
SendTagsCallBack sendTagsCallBack = (SendTagsCallBack) getActivity();
if (null != sendTagsCallBack)
{
sendTagsCallBack.onTaskStarts();
}
}
private void transfareTaskEndsToActivity()
{
SendTagsCallBack sendTagsCallBack = (SendTagsCallBack) getActivity();
if (null != sendTagsCallBack)
{
sendTagsCallBack.onTaskEnds();
}
}
private void transfareStatusToActivity()
{
SendTagsCallBack sendTagsCallBack = (SendTagsCallBack) getActivity();
if (null != sendTagsCallBack)
{
sendTagsCallBack.onStatusChange(mSendTagsStatus);
}
}
private Map<String, Object> generateTags(String tagInt, String tagString)
{
Map<String, Object> tags = new HashMap<String, Object>();
if (tagInt.length() != 0)
{
tags.put("FavNumber", Integer.parseInt(tagInt));
}
if (tagString.length() != 0)
{
tags.put("Alias", tagString);
}
return tags;
}
}
I gave these permissions in Manifest file
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<!--library-->
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<!-- GCM connects to Google Services. -->
<uses-permission android:name="android.permission.INTERNET"/>
<!-- GCM requires a Google account. -->
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<!-- Keeps the processor from sleeping when a message is received. -->
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<!--
Creates a custom permission so only this app can receive its messages.
NOTE: the permission *must* be called PACKAGE.permission.C2D_MESSAGE,
where PACKAGE is the application's package name.
-->
<permission
android:name="com.pushwoosh.test.tags.sample.app.permission.C2D_MESSAGE"
android:protectionLevel="signature"/>
<uses-permission
android:name="com.pushwoosh.test.tags.sample.app.permission.C2D_MESSAGE"/>
<!-- This app has permission to register and receive data message. -->
<uses-permission
android:name="com.google.android.c2dm.permission.RECEIVE"/>
<intent-filter>
<action android:name="com.pushwoosh.test.tags.sample.app.MESSAGE"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<activity android:name="com.arellomobile.android.push.PushWebview"/>
<activity android:name="com.arellomobile.android.push.MessageActivity"/>
<activity android:name="com.arellomobile.android.push.PushHandlerActivity"/>
<!--
BroadcastReceiver that will receive intents from GCM
services and handle them to the custom IntentService.
The com.google.android.c2dm.permission.SEND permission is necessary
so only GCM services can send data messages for the app.
-->
<receiver
android:name="com.google.android.gcm.GCMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND"
>
<intent-filter>
<!-- Receives the actual messages. -->
<action android:name="com.google.android.c2dm.intent.RECEIVE"/>
<!-- Receives the registration id. -->
<action android:name="com.google.android.c2dm.intent.REGISTRATION"/>
<category android:name="com.pushwoosh.test.tags.sample.app"/>
</intent-filter>
</receiver>
<!--
Application-specific subclass of PushGCMIntentService that will
handle received messages.
-->
<service android:name="com.arellomobile.android.push.PushGCMIntentService"/>
<!--
Service for sending location updates
-->
<service android:name="com.arellomobile.android.push.GeoLocationService"/>
In 1]Sender_Id put your "GCM App ID" and in 2]In APP ID put your "PushWoosh APP KEY" correctly
then go to PushWoosh website after logging in, go to Application part then Woosh your message.
Related
Currently i'm using PN7150 with android board.
The NFC reader (PN7150) can be used to read type A cards, but cannot detect type B cards at all.
Below is the PCB antenna that I used :
The following is a schematic for the antenna matching circuit:
Smith chart simulation results from RFSim99:
Below is the signal shape (Smith chart) of the measurement results on the PCB board using Nano VNA.
This is my android code :
MainActivity.java
package com.iwjo.nfcfieldstrength;
public class MainActivity extends AppCompatActivity implements NfcAdapter.ReaderCallback, NfcThread.UiCallback{
public static final boolean mbUsbExternalUSBManager = false;
private static final String ACTION_USB_PERMISSION = "com.iwjo.ktpfieldstrength.USB_PERMISSION";
private UsbManager mUsbManager = null;
private PendingIntent mPermissionIntent= null;
public static final int REQUEST_WRITE_PERMISSION = 786;
private static final int REQUEST_WRITE_STORAGE_REQUEST_CODE = 112;
private NfcAdapter nfcadapter;
private String[][] nfctechfilter = new String[][] { new String[] { NfcA.class.getName() } };
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver(){
public void onReceive(Context context, Intent intent){
String action = intent.getAction();
if(ACTION_USB_PERMISSION.equals(action)){
synchronized(this){
if (action.equals(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED)) {
int state = intent.getIntExtra(NfcAdapter.EXTRA_ADAPTER_STATE,
NfcAdapter.STATE_ON);
if (state == NfcAdapter.STATE_ON
|| state == NfcAdapter.STATE_TURNING_ON) {
///Log.d(TAGCL, "state: " + state);
if (state == NfcAdapter.STATE_ON) {
nfcadapter.enableReaderMode(
MainActivity.this,
MainActivity.this,
NfcAdapter.FLAG_READER_NFC_A
| NfcAdapter.FLAG_READER_NFC_B
//| NfcAdapter.FLAG_READER_NFC_F
//| NfcAdapter.FLAG_READER_NFC_V
//| NfcAdapter.FLAG_READER_NFC_BARCODE
//| NfcAdapter.FLAG_READER_NO_PLATFORM_SOUNDS
| NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK,
null);
}
} else {
showMessage(getString(R.string.nfc_not_activated));
}
}
}
}
}
};
private void requestPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_WRITE_PERMISSION);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == REQUEST_WRITE_PERMISSION && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
/////--Log.d(TAGSAM, "permission granted");
}
}
#Override
protected void onPostResume() {
//bindComponents();
super.onPostResume();
if (!nfcadapter.isEnabled()) {
showMessage(getString(R.string.nfc_not_activated));
return;
}
IntentFilter filter = new IntentFilter(
NfcAdapter.ACTION_ADAPTER_STATE_CHANGED);
//registerReceiver(mBroadcastReceiver, filter);
nfcadapter.enableReaderMode(this, this, NfcAdapter.FLAG_READER_NFC_A
| NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK | NfcAdapter.FLAG_READER_NFC_B | NfcAdapter.FLAG_READER_NFC_F, null);
}
#Override
protected void onPause() {
super.onPause();
//unregisterReceiver(mBroadcastReceiver);
nfcadapter.disableReaderMode(this);
}
#Override
protected void onDestroy() {
if( mbUsbExternalUSBManager ){
unregisterReceiver(mUsbReceiver);
}
if( mbUsbExternalUSBManager ){
unregisterReceiver(mUsbReceiver);
}
super.onDestroy();
}
#Override
public void showMessage(final String msg) {
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(MainActivity.this, msg, Toast.LENGTH_LONG).show();
}
});
}
#Override
public void setEditText(final int id, final String txt, final int status) {
runOnUiThread(new Runnable() {
#Override
public void run() {
//EditText edit = (EditText) findViewById(id);
//eMessage.setText(txt);
setMessageText(txt, status);
}
});
}
public void setMessageText(String text, int status)
{
// status 0 : normal proses, 1 : berhasil, 2 : error
}
#Override
public void setBiodata(final Biodata bio) {
runOnUiThread(new Runnable() {
#Override
public void run() {
}
});
}
#Override
public void setProgressBar(final int id, final int value) {
runOnUiThread(new Runnable() {
#Override
public void run() {
ProgressBar pbar = (ProgressBar) findViewById(id);
pbar.setProgress(value);
}
});
}
private void setErrorMessage(String text)
{
//eMessage.setBackground(Color.red());
}
#Override
public void onTagDiscovered(Tag tag) {
if(isSam_authenticate) {
Runnable nfcr = new NfcThread(this, tag, this);
new Thread(nfcr).start();
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ActionBar actionBar = getSupportActionBar();
//actionBar.setIcon(R.mipmap.ic_launcher);
actionBar.setDisplayShowHomeEnabled(true);
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
progressBar = (ProgressBar) findViewById(R.id.progressBar);
eMessage = (TextView) findViewById(R.id.eMessage);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
try {
nfcadapter = NfcAdapter.getDefaultAdapter(this);
if (nfcadapter == null) {
Toast.makeText(this, getString(R.string.nfc_unavailable), Toast.LENGTH_LONG).show();
finish();
}
} catch (Exception f) {
}
mainContext = this;
requestAppPermissions();
}
private void requestAppPermissions() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
return;
}
if (hasReadPermissions() && hasWritePermissions()) {
return;
}
ActivityCompat.requestPermissions(this,
new String[] {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
}, REQUEST_WRITE_STORAGE_REQUEST_CODE); // your request code
}
private boolean hasReadPermissions() {
return (ContextCompat.checkSelfPermission(getBaseContext(), Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED);
}
private boolean hasWritePermissions() {
return (ContextCompat.checkSelfPermission(getBaseContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED);
}
}
NfcThread.java
package com.iwjo.nfcfieldstrength;
import android.content.Context;
import android.nfc.Tag;
import android.nfc.tech.IsoDep;
import android.util.Log;
import com.iwjo.ktpfieldstrength.R;
import java.io.IOException;
public class NfcThread implements Runnable {
public static final String TAG_CL_IN = ">>";
public static final String TAG_CL_OUT = "<<";
public interface UiCallback {
void showMessage(String msg);
void setEditText(int id, String txt, int status);
void setBiodata(Biodata bio);
void setProgressBar(int id, int value);
}
private Context context;
private Tag tag;
private UiCallback cb;
public NfcThread(Context context, Tag tag, UiCallback cb) {
this.context = context;
this.tag = tag;
this.cb = cb;
}
private IsoDep iso;
#Override
public void run() {
iso = IsoDep.get(tag);
if (iso == null) {
cb.showMessage(context.getString(R.string.non_iso));
return;
}
try {
iso.connect();
} catch (IOException e) {
cb.showMessage(context.getString(R.string.iso_connect_error));
Log.e(TAG, context.getString(R.string.iso_connect_error) + " : " + e.getMessage());
return;
}
try {
byte[] uid = iso.getTag().getId();
String ret = StringUtils.convertByteArrayToHexString(uid);
cb.showMessage("Card detected, UID : "+ret);
cb.setEditText(R.id.eMessage, "", 0);
} catch (Exception e) {
} finally {
try {
iso.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
private String send_apdu(String sapdu) throws IOException {
//Log.i(TAG, "SEND -> " + sapdu);
final byte [] apdu = StringUtils.convertHexStringToByteArray(StringUtils.removeSpaces(sapdu));
byte [] recv = iso.transceive(apdu);
String ret = StringUtils.convertByteArrayToHexString(recv);
Log.i(TAG_CL_OUT, ret);
return ret;
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.iwjo.nfcfieldstrength">
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.NFC" />
<uses-feature android:name="android.hardware.nfc" android:required="true" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<permission android:name="android.permission.REBOOT" />
<permission android:name="android.permission.MODIFY_PHONE_STATE" />
<permission android:name="android.permission.DEVICE_POWER" />
<uses-feature android:name="android.hardware.usb.host" />
<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"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Please give me advice..
I am working on application locker in this regard I build code which can see here below. My question is my code is running below version 20 (Lollipop) and not working with above version 20.
I have been applied almost all solutions printed at this site but failed. Some times but very rarely I got that app locker working but for limited apps like settings. Here is how I am getting package name:
private String getTopPackageName() {
if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
UsageStatsManager usm = (UsageStatsManager) this.getSystemService(Context.USAGE_STATS_SERVICE);
long time = System.currentTimeMillis();
List<UsageStats> appList = usm.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, time-1000*1000, time);
if (appList != null && appList.size() > 0) {
SortedMap<Long, UsageStats> mySortedMap = new TreeMap<Long, UsageStats>();
for (UsageStats usageStats : appList) {
mySortedMap.put(usageStats.getLastTimeUsed(), usageStats);
}
if (mySortedMap != null && !mySortedMap.isEmpty()) {
currentApp = mySortedMap.get(mySortedMap.lastKey()).getPackageName();
}
}
} else {
mActivityManager = (ActivityManager)this.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> tasks = mActivityManager.getRunningAppProcesses();
currentApp = tasks.get(0).processName;
}
return currentApp;
}
Also here is my whole Service Class
public class AppLockService extends Service {
public static final String BROADCAST_SERVICE_STARTED = "com.appslocker.locker.intent.action.service_started";
/**
* Sent to {#link MainActivity} when the service has been stopped
*/
public static final String BROADCAST_SERVICE_STOPPED = "com.appslocker.locker.intent.action.service_stopped";
/**
* This category allows the receiver to receive actions relating to the
* state of the service, such as when it is started or stopped
*/
public static final String CATEGORY_STATE_EVENTS = "com.appslocker.locker.intent.category.service_start_stop_event";
private static final int REQUEST_CODE = 0x1234AF;
public static final int NOTIFICATION_ID = 0xABCD32;
private static final String TAG = "AppLockService";
/**
* Use this action to stop the intent
*/
private static final String ACTION_STOP = "com.apsscloker.locker.intent.action.stop_lock_service";
/**
* Starts the alarm
*/
private static final String ACTION_START = "com.appslocker.locker.intent.action.start_lock_service";
/**
* When specifying this action, the service will initialize everything
* again.<br>
* This has only effect if the service was explicitly started using
* {#link #getRunIntent(Context)}
*/
private static final String ACTION_RESTART = "com.appslocker.locker.intent.action.restart_lock_service";
private static final String EXTRA_FORCE_RESTART = "com.appslocker.locker.intent.extra.force_restart";
private ActivityManager mActivityManager;
/**
* 0 for disabled
*/
private long mShortExitMillis;
private boolean mRelockScreenOff;
private boolean mShowNotification;
private boolean mExplicitStarted;
private boolean mAllowDestroy;
private boolean mAllowRestart;
private Handler mHandler;
private BroadcastReceiver mScreenReceiver;
private String currentApp;
/**
* This map contains locked apps in the form<br>
* <PackageName, ShortExitEndTime>
*/
private Map<String, Boolean> mLockedPackages;
private Map<String, Runnable> mUnlockMap;
#Override
public IBinder onBind(Intent i) {
return new LocalBinder();
}
public class LocalBinder extends Binder {
public AppLockService getInstance() {
return AppLockService.this;
}
}
private final class ScreenReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
Log.i(TAG, "Screen ON");
// Trigger package again
mLastPackageName = "";
startAlarm(AppLockService.this);
}
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
Log.i(TAG, "Screen OFF");
stopAlarm(AppLockService.this);
if (mRelockScreenOff) {
lockAll();
}
}
}
}
;
#Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "onCreate");
}
/**
* Starts everything, including notification and repeating alarm
*
* #return True if all OK, false if the service is not allowed to start (the
* caller should stop the service)
*/
private boolean init() {
Log.d(TAG, "init");
if (new PrefUtils(this).isCurrentPasswordEmpty()) {
Log.w(TAG, "Not starting service, current password empty");
return false;
}
mHandler = new Handler();
mActivityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
mUnlockMap = new HashMap<>();
mLockedPackages = new HashMap<>();
mScreenReceiver = new ScreenReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
registerReceiver(mScreenReceiver, filter);
final Set<String> apps = PrefUtils.getLockedApps(this);
for (String s : apps) {
mLockedPackages.put(s, true);
}
PrefUtils prefs = new PrefUtils(this);
boolean delay = prefs.getBoolean(R.string.pref_key_delay_status,
R.bool.pref_def_delay_status);
if (delay) {
int secs = prefs.parseInt(R.string.pref_key_delay_time,
R.string.pref_def_delay_time);
mShortExitMillis = secs * 1000;
}
mRelockScreenOff = prefs.getBoolean(
R.string.pref_key_relock_after_screenoff,
R.bool.pref_def_relock_after_screenoff);
startNotification();
startAlarm(this);
// Tell MainActivity we're done
Intent i = new Intent(BROADCAST_SERVICE_STARTED);
i.addCategory(CATEGORY_STATE_EVENTS);
sendBroadcast(i);
return true;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Log.d(TAG, "test");
if (intent == null || ACTION_START.equals(intent.getAction())) {
if (!mExplicitStarted) {
Log.d(TAG, "explicitStarted = false");
if (init() == false) {
doStopSelf();
return START_NOT_STICKY;
}
mExplicitStarted = true;
}
checkPackageChanged();
} else if (ACTION_RESTART.equals(intent.getAction())) {
if (mExplicitStarted
|| intent.getBooleanExtra(EXTRA_FORCE_RESTART, false)) {
Log.d(TAG,
"ACTION_RESTART (force="
+ intent.getBooleanExtra(EXTRA_FORCE_RESTART,
false));
// init();
doRestartSelf(); // not allowed, so service will restart
} else {
doStopSelf();
}
} else if (ACTION_STOP.equals(intent.getAction())) {
Log.d(TAG, "ACTION_STOP");
doStopSelf();
}
return START_STICKY;
}
private String mLastPackageName;
private void checkPackageChanged() {
final String packageName = getTopPackageName();
// final String completeName = packageName + "/"
// + top.topActivity.getShortClassName();
if (!packageName.equals(mLastPackageName)) {
Log.d(TAG, "appchanged " + " (" + mLastPackageName + ">"
+ packageName + ")");
onAppClose(mLastPackageName, packageName);
onAppOpen(packageName, mLastPackageName);
}
// prepare for next call
mLastPackageName = packageName;
// mLastCompleteName = completeName;
}
private void onAppOpen(final String open, final String close) {
if (mLockedPackages.containsKey(open)) {
onLockedAppOpen(open);
}
}
private void onLockedAppOpen(final String open) {
final boolean locked = mLockedPackages.get(open);
// Log.d(TAG, "onLockedAppOpen (locked=" + locked + ")");
if (locked) {
showLocker(open);
}
removeRelockTimer(open);
}
private void showLocker(String packageName) {
Intent intent = LockService.getLockIntent(getApplicationContext(), packageName);
intent.setAction(LockService.ACTION_COMPARE);
intent.putExtra(LockService.EXTRA_PACKAGENAME, packageName);
startService(intent);
}
private void showLockerForCategory(String category) {
Intent intent = LockService.getLockIntentForCategory(this, category);
intent.setAction(LockService.ACTION_COMPARE);
intent.putExtra(LockService.EXTRA_CATEGORY, category);
startService(intent);
}
private void onAppClose(String close, String open) {
if (mLockedPackages.containsKey(close)) {
onLockedAppClose(close, open);
}
}
private void onLockedAppClose(String close, String open) {
//showInterstitial();
setRelockTimer(close);
if (getPackageName().equals(close) || getPackageName().equals(open)) {
// Don't interact with own app
return;
}
if (mLockedPackages.containsKey(open)) {
// The newly opened app needs a lock screen, so don't hide previous
return;
}
LockService.hide(this);
}
private void setRelockTimer(String packageName) {
boolean locked = mLockedPackages.get(packageName);
if (!locked) {
if (mShortExitMillis != 0) {
Runnable r = new RelockRunnable(packageName);
mHandler.postDelayed(r, mShortExitMillis);
mUnlockMap.put(packageName, r);
} else {
lockApp(packageName);
}
}
}
private void removeRelockTimer(String packageName) {
// boolean locked = mLockedPackages.get(packageName);
// if (!locked) {
if (mUnlockMap.containsKey(packageName)) {
mHandler.removeCallbacks(mUnlockMap.get(packageName));
mUnlockMap.remove(packageName);
}
}
/**
* This class will re-lock an app
*/
private class RelockRunnable implements Runnable {
private final String mPackageName;
public RelockRunnable(String packageName) {
mPackageName = packageName;
}
#Override
public void run() {
lockApp(mPackageName);
}
}
List<RunningTaskInfo> mTestList = new ArrayList<>();
private String getTopPackageName() {
if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
UsageStatsManager usm = (UsageStatsManager) this.getSystemService(Context.USAGE_STATS_SERVICE);
long time = System.currentTimeMillis();
List<UsageStats> appList = usm.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, time-1000*1000, time);
if (appList != null && appList.size() > 0) {
SortedMap<Long, UsageStats> mySortedMap = new TreeMap<Long, UsageStats>();
for (UsageStats usageStats : appList) {
mySortedMap.put(usageStats.getLastTimeUsed(), usageStats);
}
if (mySortedMap != null && !mySortedMap.isEmpty()) {
currentApp = mySortedMap.get(mySortedMap.lastKey()).getPackageName();
}
}
} else {
mActivityManager = (ActivityManager)this.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> tasks = mActivityManager.getRunningAppProcesses();
currentApp = tasks.get(0).processName;
}
return currentApp;
/* if (Build.VERSION.SDK_INT > 20) {
return mActivityManager.getRunningAppProcesses().get(0).processName;
// mClassName = activityManager.getRunningAppProcesses().get(0).getClass().getName();
} else {
return mActivityManager.getRunningTasks(1).get(0).topActivity.getPackageName();
// mClassName = activityManager.getRunningTasks(1).get(0).topActivity.getClassName();
}*/
}
public void unlockApp(String packageName) {
Log.d(TAG, "unlocking app (packageName=" + packageName + ")");
if (mLockedPackages.containsKey(packageName)) {
mLockedPackages.put(packageName, false);
}
}
private void lockAll() {
for (Map.Entry<String, Boolean> entry : mLockedPackages.entrySet()) {
entry.setValue(true);
}
}
void lockApp(String packageName) {
if (mLockedPackages.containsKey(packageName)) {
mLockedPackages.put(packageName, true);
}
}
private void startNotification() {
// Start foreground anyway
startForegroundWithNotification();
mShowNotification = new PrefUtils(this).getBoolean(
R.string.pref_key_show_notification,
R.bool.pref_def_show_notification);
}
#SuppressLint("InlinedApi")
private void startForegroundWithNotification() {
Log.d(TAG, "showNotification");
boolean hide = new PrefUtils(this).getBoolean(
R.string.pref_key_hide_notification_icon,
R.bool.pref_def_hide_notification_icon);
int priority = hide ? Notification.PRIORITY_MIN
: Notification.PRIORITY_DEFAULT;
Intent i = new Intent(this, MainActivity.class);
PendingIntent pi = PendingIntent.getActivity(this, 0, i, 0);
String title = getString(R.string.notification_title);
String content = getString(R.string.notification_state_locked);
NotificationCompat.Builder nb = new NotificationCompat.Builder(this);
nb.setSmallIcon(R.drawable.ic_launcher);
nb.setContentTitle(title);
nb.setContentText(content);
nb.setWhen(System.currentTimeMillis());
nb.setContentIntent(pi);
nb.setOngoing(true);
nb.setPriority(priority);
startForeground(NOTIFICATION_ID, nb.build());
}
public static void start(Context c) {
startAlarm(c);
}
/**
* #param c
* #return The new state for the service, true for running, false for not
* running
*/
public static boolean toggle(Context c) {
if (isRunning(c)) {
stop(c);
return false;
} else {
start(c);
return true;
}
}
public static boolean isRunning(Context c) {
ActivityManager manager = (ActivityManager) c
.getSystemService(Context.ACTIVITY_SERVICE);
for (RunningServiceInfo service : manager
.getRunningServices(Integer.MAX_VALUE)) {
if (AppLockService.class.getName().equals(
service.service.getClassName())) {
return true;
}
}
return false;
}
/**
* Starts the service
*/
private static void startAlarm(Context c) {
AlarmManager am = (AlarmManager) c.getSystemService(ALARM_SERVICE);
PendingIntent pi = getRunIntent(c);
SharedPreferences sp = PrefUtils.prefs(c);
String defaultPerformance = c.getString(R.string.pref_val_perf_normal);
String s = sp.getString(c.getString(R.string.pref_key_performance),
defaultPerformance);
if (s.length() == 0)
s = "0";
long interval = Long.parseLong(s);
Log.d(TAG, "Scheduling alarm (interval=" + interval + ")");
long startTime = SystemClock.elapsedRealtime();
am.setRepeating(AlarmManager.ELAPSED_REALTIME, startTime, interval, pi);
}
private static PendingIntent running_intent;
private static PendingIntent getRunIntent(Context c) {
if (running_intent == null) {
Intent i = new Intent(c, AppLockService.class);
i.setAction(ACTION_START);
running_intent = PendingIntent.getService(c, REQUEST_CODE, i, 0);
}
return running_intent;
}
private static void stopAlarm(Context c) {
AlarmManager am = (AlarmManager) c.getSystemService(ALARM_SERVICE);
am.cancel(getRunIntent(c));
}
/**
* Stop this service, also stopping the alarm
*/
public static void stop(Context c) {
stopAlarm(c);
Intent i = new Intent(c, AppLockService.class);
i.setAction(ACTION_STOP);
c.startService(i);
}
/**
* Re-initialize everything.<br>
* This has only effect if the service was explicitly started using
* {#link #start(Context)}
*/
public static void restart(Context c) {
Intent i = new Intent(c, AppLockService.class);
i.setAction(ACTION_RESTART);
c.startService(i);
}
/**
* Forces the service to stop and then start again. This means that if the
* service was already stopped, it will just start
*/
public static void forceRestart(Context c) {
Intent i = new Intent(c, AppLockService.class);
i.setAction(ACTION_RESTART);
i.putExtra(EXTRA_FORCE_RESTART, true);
c.startService(i);
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy: (mAllowRestart=" + mAllowRestart + ")");
if (mScreenReceiver != null)
unregisterReceiver(mScreenReceiver);
if (mShowNotification)
stopForeground(true);
if (mAllowRestart) {
start(this);
mAllowRestart = false;
return;
}
Log.i(TAG, "onDestroy (mAllowDestroy=" + mAllowDestroy + ")");
if (!mAllowDestroy) {
Log.d(TAG, "Destroy not allowed, restarting service");
start(this);
} else {
// Tell MainActivity we're stopping
Intent i = new Intent(BROADCAST_SERVICE_STOPPED);
i.addCategory(CATEGORY_STATE_EVENTS);
sendBroadcast(i);
}
mAllowDestroy = false;
}
private void doStopSelf() {
stopAlarm(this);
mAllowDestroy = true;
stopForeground(true);
stopSelf();
}
private void doRestartSelf() {
Log.d(TAG, "Setting allowrestart to true");
mAllowRestart = true;
stopSelf();
}
}
And Here is my Manifest.xml
<uses-sdk
android:minSdkVersion="15"
android:targetSdkVersion="23" />
<supports-screens
android:anyDensity="true"
android:largeScreens="true"
android:normalScreens="true"
android:smallScreens="true" />
<uses-feature
android:name="android.hardware.telephony"
android:required="false" />
<uses-feature
android:name="android.hardware.usb.accessory"
android:required="false" />
<uses-feature
android:name="android.hardware.usb.host"
android:required="false" />
<uses-feature
android:name="android.hardware.location"
android:required="false" />
<uses-feature
android:name="android.hardware.wifi"
android:required="false" />
<!-- permissions -->
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_DOCUMENTS" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<application
android:allowBackup="false"
android:icon="#drawable/ic_launcher"
android:label="#string/application_name"
android:theme="#style/Theme.AppCompat"
android:largeHeap="true"
tools:node="replace">
<activity
android:name="com.appslocker.locker.ui.MainActivity"
android:label="#string/application_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.intent.action.SEARCH" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name="com.appslocker.locker.lock.AppLockService" />
<service android:name="com.appslocker.locker.lock.LockService" />
<receiver android:name="com.appslocker.locker.receivers.BootCompleteReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
<action android:name="android.app.action.ACTION_DEVICE_ADMIN_DISABLE_REQUESTED" />
<action android:name="android.app.action.ACTION_DEVICE_ADMIN_DISABLED" />
</intent-filter>
</receiver>
<receiver
android:name=".DeviceAdmenReciever"
android:permission="android.permission.BIND_DEVICE_ADMIN">
<meta-data
android:name="android.app.device_admin"
android:resource="#xml/device_admin" />
<intent-filter>
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
<action android:name="android.app.action.ACTION_DEVICE_ADMIN_DISABLE_REQUESTED" />
<action android:name="android.app.action.ACTION_DEVICE_ADMIN_DISABLED" />
</intent-filter>
</receiver>
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<service
android:name=".MyAccessibilityService"
android:label="#string/accessibility_service_label"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE" >
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
<meta-data
android:name="android.accessibilityservice"
android:resource="#xml/accessibility_service_config" />
</service>
</application>
your application is not working because in lollipop when you install the application in your device,by default all the permission will be given by android,But From the Marshmallow the Google has added functionality that when you install any application and if it has any permission then it will ask the user for the permission,so you should search for the "runtime permission in android" in Google,And you will get the perfect code for your application.
we are using Sinch voip api. There is a bound service which starts at app start , we initialize the sinch client in the service and it is always running in the background. I tried putting the code for notification in the call screen activity as this activity will always show to accept the call. My aim is to be able to click on the notification and reopen this call activity like in whatsapp.
public class CallScreenActivity extends BaseActivity {
static final String TAG = CallScreenActivity.class.getSimpleName();
private AudioPlayer mAudioPlayer;
private Timer mTimer;
private UpdateCallDurationTask mDurationTask;
private String mCallId;
String mCaller, mReceiver;
String otherusername, myname;
private long mCallStart = 0;
private TextView mCallDuration;
private TextView mCallState;
private TextView mCallerName;
private ImageView mCallImg;
private String mk, mTimestamp;
private String mProfpic;
Button endCallButton;
Notification notification;
NotificationManager notificationManager;
private class UpdateCallDurationTask extends TimerTask {
#Override
public void run() {
CallScreenActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
updateCallDuration();
}
});
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
+ WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
| +WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| +WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
setContentView(R.layout.activity_callscreen);
mAudioPlayer = new AudioPlayer(this);
mCallDuration = (TextView) findViewById(R.id.callDuration);
mCallerName = (TextView) findViewById(R.id.remoteUser);
mCallState = (TextView) findViewById(R.id.callState);
mCallImg = (ImageView) findViewById(R.id.imgotherusr);
endCallButton = (Button) findViewById(R.id.hangupButton);
endCallButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
endCall();
}
});
mCallStart = System.currentTimeMillis();
mCallId = getIntent().getStringExtra(SinchCallService.CALL_ID);
UserSession us = new UserSession(this);
mk = us.getUserKey();
myname = us.getUsername();
mCaller = getIntent().getStringExtra("calleruid");
mReceiver = getIntent().getStringExtra("receiveruid");
otherusername = getIntent().getStringExtra("otherusername");
mTimestamp = getIntent().getStringExtra("timestamp");
System.out.println(mCaller+"on create call screen activity ongoing call" + mReceiver + otherusername);
showNotification();
}
private void showNotification() {
System.out.println("show notification callscreenactivity");
Intent notificationIntent = new Intent(this, CallScreenActivity.class);
notificationIntent.setAction("ongoingcall");
notificationIntent.putExtra("calleruid", mCaller);
notificationIntent.putExtra("receiveruid", mReceiver);
notificationIntent.putExtra("otherusername", otherusername);
notificationIntent.putExtra("timestamp", mTimestamp);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Intent hangupintent = new Intent(this, CallScreenActivity.class);
hangupintent.setAction("hangupcall");
hangupintent.setAction("ongoingcall");
hangupintent.putExtra("calleruid", mCaller);
hangupintent.putExtra("receiveruid", mReceiver);
hangupintent.putExtra("otherusername", otherusername);
hangupintent.putExtra("timestamp", mTimestamp);
PendingIntent phangupintent = PendingIntent.getService(this, 0,
hangupintent, 0);
notification = new NotificationCompat.Builder(this)
.setContentTitle("In call with " + otherusername)
.setContentText("Duration " + VoiceCallHelper.formatTimespan(System.currentTimeMillis() - mCallStart))
.setSmallIcon(R.drawable.iconcall)
.setContentIntent(pendingIntent)
.addAction(R.drawable.ic_arrow_back, "Hangup",
phangupintent).build();
notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(111 /* ID of notification */, notification);
}
#Override
public void onServiceConnected() {
try {
doStuff();
} catch (NullPointerException e) {
//getSinchServiceInterface() in doStuff below throw null pointer error.
}
}
private void doStuff() {
final Call call = getSinchServiceInterface().getCall(mCallId);
if (call != null) {
call.addCallListener(new SinchCallListener());
mCallState.setText(call.getState().toString());
DBREF_USER_PROFILES.child(call.getRemoteUserId()).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
System.out.println("datasnapshot callscreenactivity otheruser" + dataSnapshot);
User u = User.parse(dataSnapshot);
mCallerName.setText(u.getName());
mProfpic = u.getProfpicurl();
Glide.with(CallScreenActivity.this).load(mProfpic).into(mCallImg);
} else {
mCallerName.setText(call.getHeaders().get("username"));
Glide.with(CallScreenActivity.this).load(R.drawable.whatsapplogo).into(mCallImg);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
} else {
Log.e(TAG, "Started with invalid callId, aborting.");
finish();
}
}
#Override
public void onPause() {
super.onPause();
mDurationTask.cancel();
mTimer.cancel();
}
#Override
public void onResume() {
super.onResume();
mTimer = new Timer();
mDurationTask = new UpdateCallDurationTask();
mTimer.schedule(mDurationTask, 0, 500);
if (getIntent() != null && getIntent().getAction() != null) {
switch (getIntent().getAction()) {
case "ongoingcall":
System.out.println("on resume call screen activity ongoing call" + mCaller + mReceiver + otherusername);
mCaller = getIntent().getStringExtra("calleruid");
mReceiver = getIntent().getStringExtra("receiveruid");
otherusername = getIntent().getStringExtra("otherusername");
mTimestamp = getIntent().getStringExtra("timestamp");
break;
case "hangupcall":
System.out.println("on resume call screen activity hangup call");
mCaller = getIntent().getStringExtra("calleruid");
mReceiver = getIntent().getStringExtra("receiveruid");
otherusername = getIntent().getStringExtra("otherusername");
mTimestamp = getIntent().getStringExtra("timestamp");
endCallButton.performClick();
break;
}
}
}
#Override
public void onBackPressed() {
startActivity(new Intent(CallScreenActivity.this, MainAct.class));
}
private void endCall() {
if (notification != null) {
System.out.println("cancelling notification in endCAll callscreenactivity");
notificationManager.cancel(111);
}
mAudioPlayer.stopProgressTone();
Call call = getSinchServiceInterface().getCall(mCallId);
if (call != null) {
call.hangup();
}
finish();
}
private void updateCallDuration() {
if (mCallStart > 0) {
mCallDuration.setText(VoiceCallHelper.formatTimespan(System.currentTimeMillis() - mCallStart));
showNotification();
}
}
private class SinchCallListener implements CallListener {
#Override
public void onCallEnded(Call call) {
CallEndCause cause = call.getDetails().getEndCause();
Log.d(TAG, "Call ended. Reason: " + cause.toString() + mk + mCaller);
if (mk != null && mCaller != null && mk.matches(mCaller)) {
mAudioPlayer.stopProgressTone();
setVolumeControlStream(AudioManager.USE_DEFAULT_STREAM_TYPE);
String endMsg = "Call ended: " + call.getDetails().toString();
Long gt = GetTimeStamp.Id();
Toast.makeText(CallScreenActivity.this, endMsg, Toast.LENGTH_LONG).show();
System.out.println(endMsg + "mtimestamp" + mTimestamp);
String cau;
String oth;
if (call.getDetails().getDuration() > 0)
cau = "completed";
else
cau = cause.toString();
CallDetails cd1 = new CallDetails(String.valueOf(call.getDetails().getDuration()), mCaller, mReceiver, cau, String.valueOf(gt), mTimestamp, mProfpic, mCallerName.getText().toString());
CallDetails cd2 = new CallDetails(String.valueOf(call.getDetails().getDuration()), mCaller, mReceiver, cau, String.valueOf(gt), mTimestamp, mProfpic, myname);
System.out.println(mCaller + "end msg callscreenactivity" + mReceiver + " " + String.valueOf(gt));
System.out.println("end msg callscreenactivity" + mReceiver + " " + DBREF.child("VoiceCalls").child(mCaller).child(String.valueOf(gt)));
//setting in mCaller mykey node at voicecalls node firebase
DBREF_CALLS.child(mCaller).child(String.valueOf(gt)).setValue(cd1);
//setting in mReceiver otheruserkey node at voicecalls node firebase
DBREF_CALLS.child(mReceiver).child(String.valueOf(gt)).setValue(cd2);
}
endCall();
}
#Override
public void onCallEstablished(Call call) {
Log.d(TAG, "Call established");
mAudioPlayer.stopProgressTone();
mCallState.setText(call.getState().toString());
setVolumeControlStream(AudioManager.STREAM_VOICE_CALL);
mCallStart = System.currentTimeMillis();
mTimestamp = GetTimeStamp.timeStamp();
}
#Override
public void onCallProgressing(Call call) {
Log.d(TAG, "Call progressing");
mAudioPlayer.playProgressTone();
}
#Override
public void onShouldSendPushNotification(Call call, List<PushPair> pushPairs) {
// Send a push through your push provider here, e.g. GCM
}
}
}
My SinchCallService class is this:
public class SinchCallService extends Service {
private static final String APP_KEY = SINCH_APPLICATION_KEY;
private static final String APP_SECRET = SINCH_SECRET_KEY;
private static final String ENVIRONMENT = "sandbox.sinch.com";
public static final String LOCATION = "LOCATION";
public static final String CALL_ID = "CALL_ID";
static final String TAG = SinchCallService.class.getSimpleName();
private SinchServiceInterface mSinchServiceInterface = new SinchServiceInterface();
private SinchClient mSinchClient;
private String mUserId;
private StartFailedListener mListener;
#Override
public void onCreate() {
super.onCreate();
UserSession us = new UserSession(this);
System.out.println("From sinchcall oncreate" + us.getUserKey());
if (!isStarted()) {
System.out.println("sinch not started callservice oncreate " + us.getUserKey());
start(us.getUserKey());
}
}
#Override
public void onDestroy() {
if (mSinchClient != null && mSinchClient.isStarted()) {
mSinchClient.terminate();
}
super.onDestroy();
}
public void start(String userName) {
System.out.println("sinch call service start " + userName);
if (mSinchClient == null) {
mUserId = userName;
mSinchClient = Sinch.getSinchClientBuilder().context(getApplicationContext()).userId(userName)
.applicationKey(APP_KEY)
.applicationSecret(APP_SECRET)
.environmentHost(ENVIRONMENT).build();
mSinchClient.setSupportCalling(true);
mSinchClient.startListeningOnActiveConnection();
mSinchClient.addSinchClientListener(new MySinchClientListener());
mSinchClient.getCallClient().addCallClientListener(new SinchCallClientListener());
mSinchClient.start();
System.out.println(" sinch client started");
}
}
private void stop() {
if (mSinchClient != null) {
mSinchClient.terminate();
mSinchClient = null;
}
}
private boolean isStarted() {
return (mSinchClient != null && mSinchClient.isStarted());
}
#Override
public IBinder onBind(Intent intent) {
return mSinchServiceInterface;
}
public class SinchServiceInterface extends Binder {
public SinchCallService getService() {
return SinchCallService.this;
}
public Call callPhoneNumber(String phoneNumber) {
return mSinchClient.getCallClient().callPhoneNumber(phoneNumber);
}
public Call callUser(String userId) {
return mSinchClient.getCallClient().callUser(userId);
}
public Call callUser(String userId, Map<String, String> headers) {
if(!isStarted()){
UserSession us = new UserSession(getApplicationContext());
startClient(us.getUserKey());
}
return mSinchClient.getCallClient().callUser(userId, headers);
}
public String getUserName() {
return mUserId;
}
public boolean isStarted() {
return SinchCallService.this.isStarted();
}
public void startClient(String userName) {
System.out.println("startClient called sinchcallservice" + userName);
if (!isStarted()) {
System.out.println("startClient not started callservice " + userName);
start(userName);
}
}
public void stopClient() {
stop();
}
public void setStartListener(StartFailedListener listener) {
mListener = listener;
}
public Call getCall(String callId) {
return mSinchClient.getCallClient().getCall(callId);
}
}
public interface StartFailedListener {
void onStartFailed(SinchError error);
void onStarted();
}
private class MySinchClientListener implements SinchClientListener {
#Override
public void onClientFailed(SinchClient client, SinchError error) {
if (mListener != null) {
mListener.onStartFailed(error);
}
mSinchClient.terminate();
mSinchClient = null;
}
#Override
public void onClientStarted(SinchClient client) {
Log.d(TAG, "SinchClient started");
if (mListener != null) {
mListener.onStarted();
}
}
#Override
public void onClientStopped(SinchClient client) {
Log.d(TAG, "SinchClient stopped");
}
#Override
public void onLogMessage(int level, String area, String message) {
switch (level) {
case Log.DEBUG:
Log.d(area, message);
break;
case Log.ERROR:
Log.e(area, message);
break;
case Log.INFO:
Log.i(area, message);
break;
case Log.VERBOSE:
Log.v(area, message);
break;
case Log.WARN:
Log.w(area, message);
break;
}
}
#Override
public void onRegistrationCredentialsRequired(SinchClient client,
ClientRegistration clientRegistration) {
}
}
private class SinchCallClientListener implements CallClientListener {
#Override
public void onIncomingCall(CallClient callClient, Call call) {
Log.e(TAG, "Incoming call");
Intent intent = new Intent(SinchCallService.this, IncomingCallScreenActivity.class);
intent.putExtra(CALL_ID, call.getCallId());
intent.putExtra(LOCATION, call.getHeaders().get("location"));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
SinchCallService.this.startActivity(intent);
}
}
}
Following is my BaseActivity.java :
public abstract class BaseActivity extends FragmentActivity implements ServiceConnection {
private SinchCallService.SinchServiceInterface mSinchServiceInterface;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getApplicationContext().bindService(new Intent(this, SinchCallService.class), this,
BIND_AUTO_CREATE);
}
#Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
if (SinchCallService.class.getName().equals(componentName.getClassName())) {
mSinchServiceInterface = (SinchCallService.SinchServiceInterface) iBinder;
onServiceConnected();
}
}
#Override
public void onServiceDisconnected(ComponentName componentName) {
if (SinchCallService.class.getName().equals(componentName.getClassName())) {
mSinchServiceInterface = null;
onServiceDisconnected();
}
}
protected void onServiceConnected() {
// for subclasses
}
protected void onServiceDisconnected() {
// for subclasses
}
protected SinchCallService.SinchServiceInterface getSinchServiceInterface() {
return mSinchServiceInterface;
}
}
I have tried things like setting
android:launchMode="singleTop"
If I backpress on the CallScreenActivity and click on notification, it opens the MainAct not the CallScreenActivity. How to make it open the CallScreenActivity?
I tried a solution with creating a stackbuilder and passing it to pending intent as follows:
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(CallScreenActivity.class);
stackBuilder.addNextIntent(notificationIntent);
PendingIntent pendingIntent =
stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
And also changed the manifest as follows:
<activity
android:launchMode="singleTop"
android:name=".activity.calls.CallScreenActivity"
android:screenOrientation="portrait"
android:parentActivityName=".activity.main.MainAct">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".activity.main.MainAct"/>
</activity>
But the above change leads to app crash with following error:
07-06 23:38:52.353 9182-9182/com.app E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.NullPointerException: Attempt to invoke interface method 'com.sinch.android.rtc.calling.CallClient com.sinch.android.rtc.SinchClient.getCallClient()' on a null object reference
at com.app.services.SinchCallService$SinchServiceInterface.getCall(SinchCallService.java:150)
at com.app.activity.calls.CallScreenActivity.endCall(CallScreenActivity.java:265)
at com.app.activity.calls.CallScreenActivity.access$100(CallScreenActivity.java:51)
at com.app.activity.calls.CallScreenActivity$1.onClick(CallScreenActivity.java:110)
at android.view.View.performClick(View.java:5207)
at android.view.View$PerformClick.run(View.java:21177)
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:5438)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:738)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:628)
So If i am using the code without the stackbuilder and i press home button, then press the notification my CallSCreenACtivity opens, but if i press back button inside the CAllSCreenACtivity and then press home button then i press notification, it opens the main acitivty instead of the CallSCreenACtivity. My call is still actvity even after pressing the backbutton on callscreenactivty.
Also I have noticed that the duration of the call being shown in the notification has stopped refreshing after back press on the CallScreenActivity but the call is still active.
Flow of the app:
For Caller:-
When app starts, MainAct starts,from where a user clicks on someone's profile and is taken to ProfilesAct where he presses the call button to call that person and is taken to the CallScreenActivity.
MainAct->ProfilesACt->CallScreenACt
For Receiver:-
App is in background, the call comes, the SinchCallService makes the IncomingCAllAct to show, when he accepts the call he is taken to the CallScreenActivity.
IncomingCallAct->CallSCreeenACtivity
or could be suppose receiver is already using the app, then
any activity(could be chat activity, main acitivty etc)->IncomingCallAct->CallSCreeenACtivity
Manifest of the app:-
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.app.t">
<application
android:name=".TApplication"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/Theme.AppCompat.Light.NoActionBar">
<activity
android:name=".SplashAct"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".activity.userprofile.UserProfileAct"
android:screenOrientation="portrait" />
<activity
android:name=".activity.videocalls.VideoCallScreenActivity"
android:screenOrientation="portrait"
android:launchMode="singleTop"/>
<activity
android:name=".activity.videocalls.IncomingVideoCallScreenActivity"
android:screenOrientation="portrait"
android:noHistory="true"/>
<activity
android:name=".activity.main.MainAct"
android:launchMode="singleTop"
android:screenOrientation="portrait"></activity>
<activity android:name=".activity.chat.ChatActivity" />
<service android:name=".services.MyFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<service android:name=".services.MyFirebaseInstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
<activity android:name=".activity.settings.SettingsmainActivity" />
<service android:name=".services.SinchCallService"></service>
<activity
android:name=".activity.calls.CallScreenActivity"
android:launchMode="singleTop"
android:screenOrientation="portrait" />
<activity
android:name=".activity.calls.IncomingCallScreenActivity"
android:noHistory="true"
android:screenOrientation="portrait" />
<activity android:name=".activity.chat.NewChatActivity" />
<activity android:name=".activity.chat.ChatActivity1"/>
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths" />
</provider>
</application>
</manifest>
There is no need to make the CallScreenActivity in the mainfest as singletask or singletop, just store the call parameters like callid(which helps Sinch api in recognizing the specific call), call start time, etc in sharedpreferences or sqlite db, make the notification intent like following :
Intent notificationIntent = new Intent(getApplicationContext(), CallScreenActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0,
notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Notification notification = new NotificationCompat.Builder(getApplicationContext())
.setContentTitle("In call with " + otherusername)
.setSmallIcon(R.drawable.iconcall)
.setContentIntent(pendingIntent).build();
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(111 /* ID of notification */, notification);
As long as we pass the right callid we will be able to resume call by clicking the notification.
I have a method "send()" that send values to the server and then get response 0 or 1 from the server. then i want to active a method that check if its 0 or 1 and then i want to active a method that on MainActivity that called from the service.
this is the service code
public class SendThreadCommunication extends Thread {
private final static String TAG = "SendThreadCommunication";
private final int READ_TIMEOUT = 100000;
private final int CONNECTION_TINEOUT = 100000;
private Looper myLooper;
private int mResponseCode;
private String mData = "";
private final ServerRequest req;
// private RegisterUser user;
private static String ans;
public SendThreadCommunication(ServerRequest req) {
this.req = req;
}
public String readWebData(InputStream stream) {
String line = "";
StringBuffer buffer = new StringBuffer();
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
try {
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
reader.close();
} catch (IOException e) {
// TODO Auto-generated catch block
}
return buffer.toString();
}
#Override
public void run() {
try {
send();
// evaluateDataAndRespondToFragment(mData);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void send() throws ClientProtocolException, IOException {
OutputStream mOutputStream = null;
BufferedWriter mWriter = null;
List<NameValuePair> mParameters = req.getParameters();
URL url = null;
HttpURLConnection connection = null;
try {
Looper.prepare();
url = new URL(req.returnRequestUrl());
connection = (HttpURLConnection) url.openConnection();
connection.setReadTimeout(READ_TIMEOUT);
connection.setConnectTimeout(CONNECTION_TINEOUT);
connection.setRequestMethod(Params.HTTP_REQUEST_METHOD_POST);
connection.setDoOutput(true);
connection.setDoInput(true);
mOutputStream = connection.getOutputStream();
mWriter = new BufferedWriter(new OutputStreamWriter(mOutputStream, Params.UTF8));
String sparams = URLEncodedUtils.format(mParameters, Params.UTF8);
mWriter.write(sparams);
mWriter.flush();
mResponseCode = connection.getResponseCode();
if (mResponseCode > 203) {
mData = readWebData(connection.getErrorStream());
//this.req.getResponse().notGoodServerEroorr();
} else {
mData = readWebData(connection.getInputStream());
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (connection != null) {
try {
if (mOutputStream != null)
mOutputStream.close();
if (mWriter != null)
mWriter.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
connection.disconnect();
evaluateDataAndRespondToFragment(mData);
myLooper = Looper.myLooper();
Looper.loop();
myLooper.quit();
}
}
}
private void evaluateDataAndRespondToFragment(String mData) {
Listen lis = this.req.getResponse();
if (mData.equals("1"))
lis.good();
else
lis.notGood();
if (mData.equals("0"))
{
lis.userGcmNotRegistered();
}
}
}
this service code send to the server values and get response. the method "evaluateDataAndRespondToFragment" check if its 0 or 1 and then active the appropriate method. that method should trigger other method in the MainActivity.
i know that runOnUiThread handle this, but i dont know how to use it.
the method on the MainActivity change the UI.
this is the MainActivity code
public class MainActivity extends Activity implements SensorEventListener, Listen {
private BroadcastReceiver statusReceiver;
private IntentFilter mIntent;
Sensor accelerometer;
SensorManager sm;
TextView acceleration;
SendValues sv;
int counter3 = 0;
int counter5 = 0;
int pastTime = 0;
private static final String TAG = "MainActivity";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public void good() {
Toast.makeText(getApplication(), "successful transfer", Toast.LENGTH_LONG).show();
}
#Override
public void notGood() {
Toast.makeText(getApplication(), "UNsuccssful transfer", Toast.LENGTH_LONG).show();
}
#Override
public void userGcmNotRegistered() {
Toast.makeText(getApplication(), "There is some problem, please register again to the App", Toast.LENGTH_LONG).show();
}
}
Here it should active one of the methods "good","not good"....
i know that runOnUiThread handle it but i dont know how to use it and where.
if anyone could tell me what to do i will appreciate.
A service doesn't have a runOnUiThread method, but you can use intent instead of.
Simply,
Add a BroadcastReceiver to your activity,
Add receiver to your AndroidManifest.xml,
Send intent from your service.
MainActivity.java
public class MainActivity extends Activity implements SensorEventListener, Listen {
private BroadcastReceiver statusReceiver;
private IntentFilter mIntent;
Sensor accelerometer;
SensorManager sm;
TextView acceleration;
SendValues sv;
int counter3 = 0;
int counter5 = 0;
int pastTime = 0;
private static final String TAG = "MainActivity";
statusReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
switch(intent.getIntExtra("status", -1) {
case 1:
good();
break;
case 2:
notGood();
break;
default:
userGcmNotRegistered();
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
registerReceiver(statusReceiver, new IntentFilter("com.yourpackage.yourapp.GET_STATUS_INTENT");
}
#Override
public void good() {
Toast.makeText(getApplication(), "successful transfer", Toast.LENGTH_LONG).show();
}
#Override
public void notGood() {
Toast.makeText(getApplication(), "UNsuccssful transfer", Toast.LENGTH_LONG).show();
}
#Override
public void userGcmNotRegistered() {
Toast.makeText(getApplication(), "There is some problem, please register again to the App", Toast.LENGTH_LONG).show();
}
}
A simple AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.yourpackage.yourapp"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="19"
android:targetSdkVersion="19" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.yourpackage.yourapp.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>
<receiver android:name="MainActivity">
<intent-filter>
<action android:name="com.yourpackage.yourapp.GET_STATUS_INTENT">
</action>
</intent-filter>
</receiver>
</application>
</manifest>
evaluateDataAndRespondToFragment method
private void evaluateDataAndRespondToFragment(String mData) {
Intent intent = new Intent("com.yourpackage.yourapp.GET_STATUS_INTENT");
intent.putExtra(status, mData);
sendBroadcast(intent);
}
}
Additionally you need to register/unregister within your activity's onResume/onPause methods.
A bit off topic; but, Beremaran's answer is correct, you can't get the main thread from a service. However, runOnUiThread is a very important concept to know and use, to avoid blocking up your main thread. Blocking your main thread will cause the system to kill your app.
Let say you have some networking tasks to do, and you know that it can take some time to do that. Therefore you start a new Thread to do the slow work.
new Thread(new Runnable() {
#Override
public void run() {
messageFromSlowStuff = doSomeSlowStuff();
};
}).start();
Now you might want to populate the UI with the new data messageFromSlowStuff, but you can't because it is only aloud from the main thread.
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
myTextView.setText(messageFromSlowStuff)
}
});
If you are only updating a view as in the example above you can use View.post() an alternative to runOnUiThread.
myTextView.post(new Runnable() {
public void run() {
messageFromSlowStuff = doSomeSlowStuff();
myTextView.setText(messageFromSlowStuff);
}
});
Here's the docs regarding View.post(): "post reference"
I'm unable to receive any calls on my android SIP application, I can register successfully with the SIP server, I can initiate call and invite other users successfully but I can't receive any calls. I don't think I have anything wrong in my SIP server or my devices as I'm able to use Sipdroid application and initiate and receive calls.
My code is as follows, which is based on SipDemo example:
public class WalkieTalkieActivity extends Activity implements View.OnTouchListener {
public static final String TAG = "WalkieTalkieActivity";
public String sipAddress = null;
public SipManager manager = null;
public SipProfile me = null;
public SipAudioCall call = null;
public IncomingCallReceiver callReceiver;
private static final int CALL_ADDRESS = 1;
private static final int SET_AUTH_INFO = 2;
private static final int UPDATE_SETTINGS_DIALOG = 3;
private static final int HANG_UP = 4;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.walkietalkie);
ToggleButton pushToTalkButton = (ToggleButton) findViewById(R.id.pushToTalk);
pushToTalkButton.setOnTouchListener(this);
// Set up the intent filter. This will be used to fire an
// IncomingCallReceiver when someone calls the SIP address used by this
// application.
IntentFilter filter = new IntentFilter();
filter.addAction("android.SipDemo.INCOMING_CALL");
callReceiver = new IncomingCallReceiver();
this.registerReceiver(callReceiver, filter);
// "Push to talk" can be a serious pain when the screen keeps turning off.
// Let's prevent that.
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
initializeManager();
}
#Override
public void onStart() {
super.onStart();
// When we get back from the preference setting Activity, assume
// settings have changed, and re-login with new auth info.
initializeManager();
}
#Override
public void onDestroy() {
super.onDestroy();
if (call != null) {
call.close();
}
closeLocalProfile();
if (callReceiver != null) {
this.unregisterReceiver(callReceiver);
}
}
public void initializeManager() {
if(manager == null) {
manager = SipManager.newInstance(this);
}
initializeLocalProfile();
}
/**
* Logs you into your SIP provider, registering this device as the location to
* send SIP calls to for your SIP address.
*/
public void initializeLocalProfile() {
if (manager == null) {
return;
}
if (me != null) {
closeLocalProfile();
}
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
String username = prefs.getString("namePref", "XXX");
String domain = prefs.getString("domainPref", "192.168.1.11");
String password = prefs.getString("passPref", "");
if (username.length() == 0 || domain.length() == 0 || password.length() == 0) {
showDialog(UPDATE_SETTINGS_DIALOG);
return;
}
try {
SipProfile.Builder builder = new SipProfile.Builder(username, domain);
builder.setPassword(password);
builder.setOutboundProxy(domain);
builder.setPort(8090);
builder.setProtocol("UDP");
me = builder.build();
Log.d(TAG, "Auto Registration: " + me.getAutoRegistration());
Log.d(TAG, "SipProfile: " + me.getUriString());
Intent i = new Intent();
i.setAction("android.SipDemo.INCOMING_CALL");
PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, Intent.FILL_IN_DATA);
manager.open(me, pi, null);
Log.d(TAG, "manage.isOpen() " + manager.isOpened(me.getUriString()));
// This listener must be added AFTER manager.open is called,
// Otherwise the methods aren't guaranteed to fire.
manager.setRegistrationListener(me.getUriString(), new SipRegistrationListener() {
public void onRegistering(String localProfileUri) {
updateStatus("Registering with SIP Server...");
}
public void onRegistrationDone(String localProfileUri, long expiryTime) {
updateStatus("Ready");
Log.d(TAG,"Registration done successfully.....");
Log.d(TAG,"Local Profile URI: " + me.getUriString());
Log.d(TAG,"Local Profile URI: " + me);
}
public void onRegistrationFailed(String localProfileUri, int errorCode,
String errorMessage) {
updateStatus("Registration failed. Please check settings. " + errorMessage);
}
});
} catch (ParseException pe) {
updateStatus("Connection Error.");
} catch (SipException se) {
updateStatus("Connection error.");
}
}
/**
* Closes out your local profile, freeing associated objects into memory
* and unregistering your device from the server.
*/
public void closeLocalProfile() {
if (manager == null) {
return;
}
try {
if (me != null) {
manager.close(me.getUriString());
}
} catch (Exception ee) {
Log.d("WalkieTalkieActivity/onDestroy", "Failed to close local profile.", ee);
}
}
/**
* Make an outgoing call.
*/
public void initiateCall() {
updateStatus(sipAddress);
try {
SipAudioCall.Listener listener = new SipAudioCall.Listener() {
// Much of the client's interaction with the SIP Stack will
// happen via listeners. Even making an outgoing call, don't
// forget to set up a listener to set things up once the call is established.
#Override
public void onCallEstablished(SipAudioCall call) {
call.startAudio();
call.setSpeakerMode(true);
call.toggleMute();
updateStatus(call);
}
#Override
public void onCallEnded(SipAudioCall call) {
updateStatus("Ready.");
}
};
Log.d(TAG,"Calling: " + sipAddress);
call = manager.makeAudioCall(me.getUriString(), sipAddress, listener, 30);
}
catch (Exception e) {
Log.i("WalkieTalkieActivity/InitiateCall", "Error when trying to close manager.", e);
if (me != null) {
try {
manager.close(me.getUriString());
} catch (Exception ee) {
Log.i("WalkieTalkieActivity/InitiateCall",
"Error when trying to close manager.", ee);
ee.printStackTrace();
}
}
if (call != null) {
call.close();
}
}
}
}
public class IncomingCallReceiver extends BroadcastReceiver {
public static final String TAG = "IncomingCallReceiver";
/**
* Processes the incoming call, answers it, and hands it over to the
* WalkieTalkieActivity.
* #param context The context under which the receiver is running.
* #param intent The intent being received.
*/
#Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG,"************************* Incoming call received.....");
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();
}
}
};
WalkieTalkieActivity wtActivity = (WalkieTalkieActivity) 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();
}
}
}
}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.sip"
android:versionCode="1"
android:versionName="1.0" >
<application android:icon="#drawable/icon" android:label="SipDemo">
<activity android:name=".WalkieTalkieActivity"
android:configChanges="orientation|keyboardHidden">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name=".SipSettings" android:label="set_preferences"/>
<receiver android:name=".IncomingCallReceiver" android:label="Call Receiver"/>
</application>
<uses-sdk android:minSdkVersion="9" />
<uses-permission android:name="android.permission.USE_SIP" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-feature android:name="android.hardware.sip.voip" android:required="true" />
<uses-feature android:name="android.hardware.wifi" android:required="true" />
<uses-feature android:name="android.hardware.microphone" android:required="true" />
</manifest>
I list some features and permission that I had in my Manifest.xml, hope it help.
<uses-feature android:name="android.software.sip" android:required="false" />
<uses-feature android:name="android.software.sip.voip" android:required="false" />
<uses-feature android:name="android.hardware.telephony" android:required="false" />
<uses-permission android:name="android.permission.CONFIGURE_SIP" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />