I have a broadcast receiver which detects oncoming notifications when the app is open and in background but when the recent app is cleared the receiver is not working please suggest me ideas.
public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// Explicitly specify that GcmIntentService will handle the intent.
ComponentName comp = new ComponentName(context.getPackageName(),
GcmIntentService.class.getName());
JSONObject json = new JSONObject();
try {
json.putOpt("userid", StorePreference.GetSharedPreferenceDetails(context, "memberid"));
json.putOpt("rid",StorePreference.GetSharedPreferenceDetails(context, "partnerid"));
json.putOpt("message", "Received");
BoundService.getInstance().onlinestatus(json);
} catch (Exception e) {
e.printStackTrace();
}
startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}
}
Manifest decleration:
<receiver
android:name="com.twogether.receivers.GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name = "com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.google.android.gcm.demo.app" />
</intent-filter>
</receiver>
Try to register your receiver in manifest, use GcmListenerService to receive messages.
google example https://github.com/googlesamples/google-services has example to do this.
<!-- gcm_receiver, this is android source-->
<receiver
android:name="com.google.android.gms.gcm.GcmReceiver"
android:exported="true"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.myapp.gcm" />
</intent-filter>
</receiver>
<!-- gcm_listener service -->
<service
android:name="com.qblinks.qmote.GcmListenerService"
android:exported="false" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
// Use this service to receive message
public class GcmListenerService extends com.google.android.gms.gcm.GcmListenerService {
public void onMessageReceived(String from, Bundle data) {
String message = data.getString("message");
Log.v(TAG, "From: " + from);
Log.v(TAG, "Message: " + message);
sendNotification(message);
}
private void sendNotification(String message) {
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.notification)
.setContentTitle("this is title")
.setStyle(new NotificationCompat.BigTextStyle().bigText(message))//multi line
.setSound(defaultSoundUri); // ring or vibrate if no ring
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(Const.NOTIFICATION_GCM /* ID of notification */, notificationBuilder.build());
}
}
When the app is close you need to wake the app up, means you need to have the permission to do that
<uses-permission android:name="android.permission.WAKE_LOCK" />
and after you can set:
AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
manager.set(AlarmManager.RTC, System.currentTimeMillis() + 5000, yourIntent);
Related
How can I keep the foreground service running even when the user quits the app?
I've tried running the service in another process, but the service still stops after I quit the app.
My AndroidManifest.xml:
<application
android:allowBackup="true"
android:dataExtractionRules="#xml/data_extraction_rules"
android:fullBackupContent="#xml/backup_rules"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.Test"
tools:targetApi="31">
<service
android:name=".Service"
android:enabled="true"
android:process=":service"
android:exported="false" />
<activity
android:process=":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>
Service.java:
public class CountdownService extends Service {
NotificationManager notificationManager;
private String createNotificationChannel(String channelId, String channelName) {
NotificationChannel chan = new NotificationChannel(channelId,
channelName, NotificationManager.IMPORTANCE_NONE);
chan.setLightColor(Color.BLUE);
chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.createNotificationChannel(chan);
return channelId;
}
NotificationCompat.Builder builder;
#NonNull
private Notification getNotification() {
String channelId = createNotificationChannel("id", "name");
builder = new NotificationCompat.Builder(this, channelId);
return builder.setOngoing(true)
.setSmallIcon(R.mipmap.ic_launcher)
.setPriority(PRIORITY_MIN)
.setCategory(Notification.CATEGORY_SERVICE)
.setContentText("Content Text")
.setSubText("Sub Text")
.setContentTitle("Content Title")
.build();
}
#Override
public void onCreate() {
super.onCreate();
startForeground(1, getNotification());
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
And in MainActivity, I start the service like this:
Intent intent = new Intent(this, Service.class);
startForegroundService(intent);
I found that this application has only one process 'service' in the phone settings, but there is no 'activity' process, what is the problem? thanks.
Define what you mean by "exit." If you mean they go into recents and swipe the app away, or go into settings and force quit, no. That's the user saying "I want this app to end". That will kill all services. Something that could run even when the user says it shouldn't is basically malware.
I am building basic calling app using TelecomManager, ConnectionService and Connection. But, When an there is an incoming call, my incomingActivity UI is not showing up. Below is the sample code so far.
In my MainActivity.java
Intent intent = new Intent(TelecomManager.ACTION_CHANGE_DEFAULT_DIALER);
intent.putExtra(TelecomManager.EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME, getPackageName());
startActivity(intent);
// ================================================================
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
TelecomManager manager = (TelecomManager) getSystemService(TELECOM_SERVICE);
// new ComponentName(getPackageName(), CallHandler.TAG), "myCallHandlerId");
PhoneAccountHandle phoneAccountHandle = new PhoneAccountHandle(
new ComponentName(getApplicationContext(), CallHandler.TAG), "myCallHandlerId");
PhoneAccount phoneAccount = PhoneAccount
.builder(phoneAccountHandle, "myCallHandlerId")
.setCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED)
.build();
manager.registerPhoneAccount(phoneAccount);
Log.i("Phone Account", "" + manager.getPhoneAccount(phoneAccountHandle));
Log.i("Phone Account", "" + manager.getPhoneAccount(phoneAccountHandle).isEnabled());
Log.i("Phone Account", "" + manager.getPhoneAccount(phoneAccountHandle).getClass());
Log.i("Phone Account isEnabled", "" + phoneAccount.isEnabled());
Bundle bundle = new Bundle();
Uri uri = Uri.fromParts(PhoneAccount.SCHEME_TEL, "555555555", null);
bundle.putParcelable(TelecomManager.EXTRA_INCOMING_CALL_ADDRESS, uri);
bundle.putParcelable(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccountHandle);
// manager.addNewIncomingCall(phoneAccountHandle, bundle);
Log.i("Permitted", "" + manager.isIncomingCallPermitted(phoneAccountHandle));
if(manager.isIncomingCallPermitted(phoneAccountHandle)){
Log.i("Call", "Incoming");
manager.addNewIncomingCall(phoneAccountHandle, bundle);
}
}
In my CallHandler.java
#RequiresApi(api = Build.VERSION_CODES.M)
public class CallHandler extends ConnectionService{
public static final String TAG = CallHandler.class.getName();
#RequiresApi(api = Build.VERSION_CODES.N_MR1)
#Override
public Connection onCreateIncomingConnection(PhoneAccountHandle connectionManagerPhoneAccount, ConnectionRequest request) {
Log.i("CallHandler","onCreateIncomingConnection");
// return super.onCreateIncomingConnection(connectionManagerPhoneAccount, request);
Context context = getApplicationContext();
Log.i("Context","" + context);
Log.i("Context","" + context.getPackageName());
Log.i("Context","" + getBaseContext());
Log.i("Context","" + context.getClass().getName());
Log.i("Context","" + context.getClass().getSimpleName());
CallConnection callConnection = new CallConnection(context);
callConnection.setInitializing();
callConnection.setActive();
callConnection.setCallerDisplayName("Manik", TelecomManager.PRESENTATION_ALLOWED);
// callConnection.setConnectionProperties(Connection.PROPERTY_SELF_MANAGED);
// callConnection.setConnectionCapabilities(Connection.CAPABILITY_HOLD & Connection.CAPABILITY_SUPPORT_HOLD);
return callConnection;
}
#Override
public void onCreateIncomingConnectionFailed(PhoneAccountHandle connectionManagerPhoneAccount, ConnectionRequest request) {
super.onCreateIncomingConnectionFailed(connectionManagerPhoneAccount, request);
}
#Override
public void onCreateOutgoingConnectionFailed(PhoneAccountHandle connectionManagerPhoneAccount, ConnectionRequest request) {
super.onCreateOutgoingConnectionFailed(connectionManagerPhoneAccount, request);
}
#Override
public Connection onCreateOutgoingConnection(PhoneAccountHandle connectionManagerPhoneAccount, ConnectionRequest request) {
return super.onCreateOutgoingConnection(connectionManagerPhoneAccount, request);
}
}
In my CallConnection.java
#RequiresApi(api = Build.VERSION_CODES.M)
public class CallConnection extends Connection {
private Context context;
#RequiresApi(api = Build.VERSION_CODES.N_MR1)
public CallConnection(Context con) {
context = con;
setConnectionProperties(PROPERTY_SELF_MANAGED);
setAudioModeIsVoip(true);
}
#Override
public void onAnswer(int videoState) {
super.onAnswer(videoState);
Log.i("Call","Answered");
}
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
public void onShowIncomingCallUi() {
Log.i("Call","Incoming Call");
super.onShowIncomingCallUi();
// MainActivity con = new MainActivity();
// Context context = con.getApplicationContext();
NotificationChannel channel = new NotificationChannel("channel", "Incoming Calls",
NotificationManager.IMPORTANCE_HIGH);
channel.setImportance(NotificationManager.IMPORTANCE_HIGH);
// other channel setup stuff goes here.
// We'll use the default system ringtone for our incoming call notification channel. You can
// use your own audio resource here.
Uri ringtoneUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
channel.setSound(ringtoneUri, new AudioAttributes.Builder()
// Setting the AudioAttributes is important as it identifies the purpose of your
// notification sound.
.setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.build());
// NotificationManager mgr = context.getSystemService(NotificationManager.class);
// mgr.createNotificationChannel(channel);
// Create an intent which triggers your fullscreen incoming call user interface.
Intent intent = new Intent(Intent.ACTION_MAIN, null);
intent.setFlags(Intent.FLAG_ACTIVITY_NO_USER_ACTION | Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setClass(context, IncomingCallScreenActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 1, intent, 0);
Log.i("Intent1","" + intent);
Log.i("Intent2","" + intent.getPackage());
Log.i("Intent3","" + intent.getType());
Log.i("Intent4","" + intent.getData());
Log.i("Intent5","" + intent.getDataString());
Log.i("Intent6","" + intent.getAction());
Log.i("Intent7","" + intent.getCategories());
Log.i("Intent8","" + intent.getExtras());
Log.i("Pending Intent","" + pendingIntent);
Log.i("Pending Intent","" + pendingIntent.getCreatorPackage());
// Build the notification as an ongoing high priority item; this ensures it will show as
// a heads up notification which slides down over top of the current content.
final Notification.Builder builder = new Notification.Builder(context);
builder.setOngoing(true);
builder.setPriority(Notification.PRIORITY_HIGH);
// Set notification content intent to take user to fullscreen UI if user taps on the
// notification body.
builder.setContentIntent(pendingIntent);
// Set full screen intent to trigger display of the fullscreen UI when the notification
// manager deems it appropriate.
builder.setFullScreenIntent(pendingIntent, true);
// Setup notification content.
builder.setSmallIcon(R.mipmap.ic_launcher);
builder.setContentTitle("Your notification title");
builder.setContentText("Your notification content.");
// Set notification as insistent to cause your ringtone to loop.
Notification notification = builder.build();
notification.flags |= Notification.FLAG_INSISTENT;
// Use builder.addAction(..) to add buttons to answer or reject the call.
NotificationManager notificationManager = context.getSystemService(
NotificationManager.class);
notificationManager.notify("Call Notification", 37, notification);
// context.startActivity(intent);
}
}
All the log messages inside onCreateIncomingConnection() and onShowIncomingCallUi() are showing up when the app launches, and not when there is an incoming call.
All the permissions in AndroidManifest.xml
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.MANAGE_OWN_CALLS" />
<!--
Needed only if your calling app reads numbers from the `PHONE_STATE`
intent action.
-->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<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=".IncomingCallScreenActivity"></activity>
<activity android:name=".CallScreenActivity" />
<activity android:name=".ContactsActivity" />
<activity android:name=".LogsActivity" />
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.DIAL" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="tel" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.DIAL" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<service
android:name=".CallHandler"
android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE">
<intent-filter>
<action android:name="android.telecom.ConnectionService" />
</intent-filter>
</service>
</application>
Any help would be appreciated. Thanks
I'm trying to send a notification at a particular time, this part works perfectly but after I reboot the phone, the service doesn't get started unless the app is opened which then starts the service. I've tried multiple solutions online but still can't fix the issue.
Activity:
private void startNotificationAlarm() {
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, ReminderBroadcastReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, (int) ((new Date().getTime() / 1000L) % Integer.MAX_VALUE), intent, 0);
Objects.requireNonNull(alarmManager).setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
BroadcastReceiver:
public class ReminderBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
Intent serviceIntent = new Intent(context, BootService.class);
intent.setAction("<package>.Receiver");
context.startService(serviceIntent);
} else {
scheduleNotification(context, intent);
}
}
private void scheduleNotification(Context context, Intent intent) {
Notification notification = new NotificationCompat.Builder(context, BaseApp.CHANNEL_ID)
.setSmallIcon(R.drawable.ic_calendar_alert)
.setContentTitle(title)
.setContentText(message)
.setColor(color)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setCategory(NotificationCompat.CATEGORY_REMINDER)
.setAutoCancel(true)
.setOnlyAlertOnce(false)
.setStyle(new NotificationCompat.BigTextStyle().bigText(message))
.build();
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Objects.requireNonNull(notificationManager).notify((int) ((new Date().getTime() / 1000L) % Integer.MAX_VALUE), notification);
}
IntentService:
public class BootService extends IntentService {
public BootService() {
super("BootService");
}
#Override
protected void onHandleIntent(Intent intent) {
if (intent != null) {
try {
Thread.sleep(5000);
startNotification();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Manifest
<receiver
android:name=".Receiver.ReminderBroadcastReceiver" android:enabled="true" android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
</intent-filter>
</receiver>
<service android:name=".Service.BootService"/>
You have to provide below permission in manifest:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
Also you have to make android:exported as true
as per android docs:
android:exported
Whether or not the broadcast receiver can receive messages from sources outside its application — "true" if it can, and
"false" if not. If "false", the only messages the broadcast receiver
can receive are those sent by components of the same application or
applications with the same user ID.
sample code
<receiver android:name=".sample.BootReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
I'm trying to send a push notification to all devices from firebase but at first i tried only in my phone, it doesn't work, after that i tried in another phone and it doesn't work either. Finally with the 3rd one it work and it work at the second one magically. What i have to do to the push notifications work in all devices?
Manifest ->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.startingandroid.firebasecloudmessaging">
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".SplashActivity" android:label="">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".MainActivity" android:label="FCM"></activity>
<service
android:name=".MyFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
<service
android:name=".MyFirebaseInstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
</application></manifest>
MyFirebaseInstanceIDService ->
public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService {
private static final String TAG = "MyFirebaseIIDService";
#Override
public void onTokenRefresh() {
//Getting registration token
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
//Displaying token in logcat
Log.e(TAG, "Refreshed token: " + refreshedToken);
}
private void sendRegistrationToServer(String token) {
//You can implement this method to store the token on your server
//Not required for current project
} }
MyFirebaseMessagingService ->
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "StartingAndroid";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
//It is optional
Log.e(TAG, "From: " + remoteMessage.getFrom());
Log.e(TAG, "Notification Message Body: " + remoteMessage.getNotification().getBody());
//Calling method to generate notification
sendNotification(remoteMessage.getNotification().getTitle(),remoteMessage.getNotification().getBody());
}
//This method is only generating push notification
private void sendNotification(String title, String messageBody) {
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,
PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(title)
.setContentText(messageBody)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder.build());
}}
SplashActivity
public class SplashActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
getSupportActionBar().hide();
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_splash);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Intent i = new Intent(SplashActivity.this,
MainActivity.class);
startActivity(i);
finish();
}
}, 4000);
}}
I'm trying to send message to my phone with this app, without using network usage, but my code doesn't work. I followed some tutorial, check android dev and I haven't found anything (in my logcat I don't have error). Could you help me to find out my problem.
My information about compilation, compiler and phone:
Android Studio 1.0.1
API 19 Android 4.4.4 (kitkat)
Build 19
Android phone version 4.4.4
Manifest:
<uses-permission android:name="android.permission.WRITE_SMS"/>
<uses-permission android:name="android.permission.READ_SMS"/>
Function of my main activity:
Context context;
String sender;
String body;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Get current context
context = this;
//App started
Toast.makeText(context, "Started", Toast.LENGTH_LONG).show();
CheckApp();
}
private void CheckApp() {
sender = "1234";
body = "Android sms body";
//Get my package name
final String myPackageName = getPackageName();
//Check if my app is the default sms app
if (!Telephony.Sms.getDefaultSmsPackage(this).equals(myPackageName)) {
//Get default sms app
String defaultSmsApp = Telephony.Sms.getDefaultSmsPackage(context);
//Change the default sms app to my app
Intent intent = new Intent( Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT);
intent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME, context.getPackageName());
startActivity(intent);
//Write the sms
WriteSms(body, sender);
//Change my sms app to the last default sms app
Intent intent2 = new Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT);
intent2.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME, defaultSmsApp);
startActivity(intent2);
}
else{
//Write the sms
WriteSms(body, sender);
}
}
//Write the sms
private void WriteSms(String message, String phoneNumber) {
//Put content values
ContentValues values = new ContentValues();
values.put(Telephony.Sms.ADDRESS, phoneNumber);
values.put(Telephony.Sms.DATE, System.currentTimeMillis());
values.put(Telephony.Sms.BODY, message);
//Insert the message
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
context.getContentResolver().insert(Telephony.Sms.Sent.CONTENT_URI, values);
}
else {
context.getContentResolver().insert(Uri.parse("content://sms/sent"), values);
}
}
Well, this is what i wanna do but with my own app and not with the app Fake Text Message that downloaded to the play store.
Make the fake message and what should i see on my default sms app:
With the help from Mike M. I finally finished my program. So, this is the code that you must add to your app to be able to send sms without using network:
Manifest:
<uses-permission android:name="android.permission.WRITE_SMS"/>
<uses-permission android:name="android.permission.READ_SMS"/>
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<!-- BroadcastReceiver that listens for incoming SMS messages -->
<receiver android:name=".SmsReceiver"
android:permission="android.permission.BROADCAST_SMS">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_DELIVER" />
</intent-filter>
</receiver>
<!-- BroadcastReceiver that listens for incoming MMS messages -->
<receiver android:name=".MmsReceiver"
android:permission="android.permission.BROADCAST_WAP_PUSH">
<intent-filter>
<action android:name="android.provider.Telephony.WAP_PUSH_DELIVER" />
<data android:mimeType="application/vnd.wap.mms-message" />
</intent-filter>
</receiver>
<!-- My activity -->
<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>
<!-- Activity that allows the user to send new SMS/MMS messages -->
<activity android:name=".ComposeSmsActivity" >
<intent-filter>
<action android:name="android.intent.action.SEND" />
<action android:name="android.intent.action.SENDTO" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="sms" />
<data android:scheme="smsto" />
<data android:scheme="mms" />
<data android:scheme="mmsto" />
</intent-filter>
</activity>
<!-- Service that delivers messages from the phone "quick response" -->
<service android:name=".HeadlessSmsSendService"
android:permission="android.permission.SEND_RESPOND_VIA_MESSAGE"
android:exported="true" >
<intent-filter>
<action android:name="android.intent.action.RESPOND_VIA_MESSAGE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="sms" />
<data android:scheme="smsto" />
<data android:scheme="mms" />
<data android:scheme="mmsto" />
</intent-filter>
</service>
</application>
Main Activity:
Context context;
Button button;
String sender,body,defaultSmsApp;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Get current context
context = this;
//Set composant
button = (Button) findViewById(R.id.button);
//Get default sms app
defaultSmsApp = Telephony.Sms.getDefaultSmsPackage(context);
//Set the number and the body for the sms
sender = "0042";
body = "Android fake message";
//Button to write to the default sms app
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
//Get the package name and check if my app is not the default sms app
final String myPackageName = getPackageName();
if (!Telephony.Sms.getDefaultSmsPackage(context).equals(myPackageName)) {
//Change the default sms app to my app
Intent intent = new Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT);
intent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME, context.getPackageName());
startActivityForResult(intent, 1);
}
}
});
}
//Write to the default sms app
private void WriteSms(String message, String phoneNumber) {
//Put content values
ContentValues values = new ContentValues();
values.put(Telephony.Sms.ADDRESS, phoneNumber);
values.put(Telephony.Sms.DATE, System.currentTimeMillis());
values.put(Telephony.Sms.BODY, message);
//Insert the message
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
context.getContentResolver().insert(Telephony.Sms.Sent.CONTENT_URI, values);
}
else {
context.getContentResolver().insert(Uri.parse("content://sms/sent"), values);
}
//Change my sms app to the last default sms
Intent intent = new Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT);
intent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME, defaultSmsApp);
context.startActivity(intent);
}
//Get result from default sms dialog pops up
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1) {
// Make sure the request was successful
if (resultCode == RESULT_OK) {
final String myPackageName = getPackageName();
if (Telephony.Sms.getDefaultSmsPackage(context).equals(myPackageName)) {
//Write to the default sms app
WriteSms(body, sender);
}
}
}
}
As a result of adding things in your manifest you must add 4 classes: SmsReceiver, MmsReceiver, ComposeSmsActivity and HeadlessSmsSendService. You can let them empty as shown below.
SmsReceiver:
public class SmsReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
}
}
MmsReceiver:
public class MmsReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
}
}
ComposeSmsActivity:
public class ComposeSmsActivity extends ActionBarActivity {
}
HeadlessSmsSendService:
public class HeadlessSmsSendService extends IntentService {
public HeadlessSmsSendService() {
super(HeadlessSmsSendService.class.getName());
}
#Override
protected void onHandleIntent(Intent intent) {
throw new UnsupportedOperationException("Not yet implemented");
}
}
If you need more help to understand this program have a look there:
Youtube - DevBytes: Android 4.4 SMS APIs
Android developers - Getting Your SMS Apps Ready for KitKat
Possiblemobile - KitKat SMS and MMS supports