I am trying to get SMS broadcasted to few mobile numbers every time the sim card is changed. Unfortunately, it doesn't work when I try it on my device. Can someone identify the issue in my following code please. The onBoot permissions are all added.
public class SendSmsOnTheft extends BroadcastReceiver
{
static void sendSMS(String destinationAddress, String text, Context context)
{
Intent intent = new Intent(context, SendSmsOnTheft.class);
PendingIntent pendingintent = PendingIntent.getActivity(context, 0, intent, 0);
SmsManager.getDefault().sendTextMessage(destinationAddress, null, text, pendingintent, null);
}
public void onReceive(Context context, Intent intent)
{
if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction()))
{
Log.d("VogueTools", "Got the Boot Event>>>");
TelephonyManager telephonymanager = (TelephonyManager)context.getSystemService("phone");
SharedPreferences sharedpreferences = context.getSharedPreferences("file", 0);
String number1 = sharedpreferences.getString("no1", "");
String number2 = sharedpreferences.getString("no2", "");
String number3 = sharedpreferences.getString("no3", "");
String number4 = sharedpreferences.getString("no4", "");
String extra = ("Mobile of IMEI NO: ")+
telephonymanager.getDeviceId()+
" is currently used" +
" by the SIM card service provider:" +
telephonymanager.getSimOperatorName().toString();
String simno = sharedpreferences.getString("simno", "");
String serialno = ((TelephonyManager)context.getSystemService("phone")).getSimSerialNumber();
if (number1.length() == 0)
{
System.exit(0);
}
if (simno.equals(serialno))
{
sendSMS(number1, extra, context);
sendSMS(number2, extra, context);
sendSMS(number3, extra, context);
sendSMS(number4, extra, context);
}
}
System.exit(0);
}
}
Here is the code that I used in my app for the same purpose:
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.telephony.TelephonyManager;
import android.telephony.gsm.SmsManager;
import android.util.Log;
import android.widget.Toast;
public class ListeningToBoot extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
// TODO Auto-generated method stub
if(intent.getAction().equals("android.intent.action.BOOT_COMPLETED"))
{
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
String urphone = tm.getLine1Number();
Log.v("Uphone","is "+urphone);
Toast.makeText(context, "MDN:"+urphone, Toast.LENGTH_SHORT).show();
SharedPreferences prefs = context.getSharedPreferences("MySimPreferences", Context.MODE_PRIVATE);
String mobile_No=prefs.getString("MDN", "un-known");
Log.v("from shared pref","MDN"+mobile_No);
String imei=prefs.getString("IMEI", "un-known");
Log.v("from shared pref","IMEI"+imei);
if(urphone.equals(mobile_No))
{
Log.v("MDN is same","shoudl do nothing");
Toast.makeText(context, "MDN no change", Toast.LENGTH_LONG).show();
}
else
{
Log.v("MDN is not same","send a message to someone");
SharedPreferences prefs_names = context.getSharedPreferences("MyPreferences", Context.MODE_PRIVATE);
String number_to_send=prefs_names.getString("Moblie_Number", "un-known");
Toast.makeText(context, "MDN changed", Toast.LENGTH_LONG).show();
String message_to_send="Your mobile number chagned:\nNew Number: "+urphone+"\nIMEI: "+imei;
SmsManager.getDefault().sendTextMessage(number_to_send, null, message_to_send, null,null);
}
}
}
}
Hope this helps.
Edit: Make sure you have given all the required permissions in manifest file.
I think we need a little more information in order to help you. Anyway, have you registered the receiver properly? You must have been something like this under application:
<receiver
android:name=".SendSmsOnTheft"
android:enabled="true"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
With permissions:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.SEND_SMS" />
Related
I am trying to implement oauth2 to enable users to login with Reddit. I have created my app on reddit with the appropriate redirect uri.
What I did:
A MainActivity with a login button. Clicking the login button, starts the authorization flow. To create the authorization request, we need to pass a pending intent that the library uses to call the appropriate component that we want it to call after authorization is successful.
Problem:
When the pending intent is made using an implicit intent (setting only action string while creating intent), the library gets a cancelled exception while invoking the pending intent. I have mentioned the action string in the intent filter for the MainActivity in manifest file also.
What I have tried:
1. I tried creating pending intent using an explicit intent (defining the activity class I want to open while creating intent), my activity's onStart is getting called with the correct intent.
2. I tried by directly invoking the pending intent (with implicit intent) from the activity itself and it got called successfully.
Observation:
1. If I use an older version of the library (v0.2.0), the pending intent with implicit intent works fine.
Current version of OpenId AppAuth library - 0.7.1
Tested on Android 9 (Pie) - OnePlus 3T
Below is my MainActivity.java
package com.prateekgrover.redditline;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import com.prateekgrover.redditline.services.RedditAuthService;
import net.openid.appauth.AuthState;
import net.openid.appauth.AuthorizationException;
import net.openid.appauth.AuthorizationRequest;
import net.openid.appauth.AuthorizationResponse;
import net.openid.appauth.AuthorizationService;
import net.openid.appauth.AuthorizationServiceConfiguration;
import net.openid.appauth.TokenRequest;
import net.openid.appauth.TokenResponse;
import java.util.UUID;
public class MainActivity extends AppCompatActivity {
private String USED_INTENT = "1";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button loginButton = findViewById(R.id.reddit_login);
loginButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Intent intent = new Intent(MainActivity.this, RedditAuthService.class);
// startService(intent);
performRedditAuthAction(MainActivity.this, "com.prateekgrover.redditline.HANDLE_AUTHORIZATION_RESPONSE");
}
});
}
public void performRedditAuthAction(Context context, String actionRedirect) {
String uuid = UUID.randomUUID().toString();
AuthorizationServiceConfiguration serviceConfiguration = new AuthorizationServiceConfiguration(
Uri.parse("https://www.reddit.com/api/v1/authorize") /* auth endpoint */,
Uri.parse("https://www.reddit.com/api/v1/access_token") /* token endpoint */
);
String clientId = "<my client id>";
Uri redirectUri = Uri.parse("com.prateekgrover.redditline://oauth2callback");
AuthorizationRequest.Builder builder = new AuthorizationRequest.Builder(
serviceConfiguration,
clientId,
"code",
redirectUri
);
builder.setState(uuid);
builder.setScopes("identity", "mysubreddits", "read", "save", "submit", "subscribe", "vote");
AuthorizationRequest request = builder.build();
AuthorizationService authorizationService = new AuthorizationService(context);
String action = actionRedirect;
Intent postAuthorizationIntent = new Intent("com.prateekgrover.redditline.HANDLE_AUTHORIZATION_RESPONSE");
PendingIntent pendingIntent = PendingIntent.getActivity(this, request.hashCode(), postAuthorizationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
authorizationService.performAuthorizationRequest(request, pendingIntent);
}
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
if (intent != null && intent.getAction() != null) {
String action = intent.getAction();
switch (action) {
case "com.prateekgrover.redditline.HANDLE_AUTHORIZATION_RESPONSE":
redirectIntent(intent);
break;
default:
}
}
}
private void redirectIntent(#Nullable Intent intent) {
if (!intent.hasExtra(USED_INTENT)) {
handleAuthorizationResponse(intent);
intent.putExtra(USED_INTENT, true);
}
}
private void handleAuthorizationResponse(Intent intent) {
AuthorizationResponse response = AuthorizationResponse.fromIntent(intent);
AuthorizationException error = AuthorizationException.fromIntent(intent);
final AuthState authState = new AuthState(response, error);
if (response != null) {
AuthorizationService service = new AuthorizationService(this);
service.performTokenRequest(response.createTokenExchangeRequest(), new AuthorizationService.TokenResponseCallback() {
#Override
public void onTokenRequestCompleted(#Nullable TokenResponse tokenResponse, #Nullable AuthorizationException exception) {
if (exception != null) {
} else {
if (tokenResponse != null) {
authState.update(tokenResponse, exception);
System.out.println(tokenResponse.accessToken + " refresh_token " + tokenResponse.refreshToken);
}
}
}
});
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
}
#Override
protected void onStart() {
super.onStart();
Intent intent = getIntent();
if (intent != null && intent.getAction() != null) {
String action = intent.getAction();
switch (action) {
case "com.prateekgrover.redditline.HANDLE_AUTHORIZATION_RESPONSE":
redirectIntent(intent);
break;
default:
}
}
}
}
Manifest File:
<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="com.prateekgrover.redditline.HANDLE_AUTHORIZATION_RESPONSE"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
Relevant parts of the library - mCompleteIntent is the PendingIntent that I sending to the library
private void extractState(Bundle state) {
if (state == null) {
Logger.warn("No stored state - unable to handle response");
finish();
return;
}
mAuthIntent = state.getParcelable(KEY_AUTH_INTENT);
mAuthorizationStarted = state.getBoolean(KEY_AUTHORIZATION_STARTED, false);
try {
String authRequestJson = state.getString(KEY_AUTH_REQUEST, null);
mAuthRequest = authRequestJson != null
? AuthorizationRequest.jsonDeserialize(authRequestJson)
: null;
} catch (JSONException ex) {
throw new IllegalStateException("Unable to deserialize authorization request", ex);
}
mCompleteIntent = state.getParcelable(KEY_COMPLETE_INTENT);
mCancelIntent = state.getParcelable(KEY_CANCEL_INTENT);
}
private void handleAuthorizationComplete() {
Uri responseUri = getIntent().getData();
Intent responseData = extractResponseData(responseUri);
if (responseData == null) {
Logger.error("Failed to extract OAuth2 response from redirect");
return;
}
responseData.setData(responseUri);
if (mCompleteIntent != null) {
Logger.debug("Authorization complete - invoking completion intent");
try {
mCompleteIntent.send(this, 0, responseData);
} catch (CanceledException ex) {
Logger.error("Failed to send completion intent", ex);
}
} else {
setResult(RESULT_OK, responseData);
}
}
In case anybody else stumbles upon this issue.
Use the example app within app-auth android github project.
Don't use Google CodeLabs app-auth example! The code from the question above is from Google CodeLabs, it is very old and no longer works (state at July 2020).
I did the same mistake, app-auth links codelabs on their own page/readme, so I started using codelabs code and ended up with lots of problems and errors.
The new app-auth version 0.7.x uses a json configuration file and the example app shows how to handle errors around pending intents etc. .
I'm trying to make a web app with push notifications. I'm using server key with no ip adress filtering so any ip is allowed (when I was adding my public shared ip from my server I was getting a 404 forbiden error...)
Now it looks like it works, when I send a message I get this :
{"multicast_id":768704xxxxx3856470,"success":1,"failure":0,"canonical_ids":0,"results":[{"message_id":"0:1430054xxxxxx71%60cd63d3f9fd7ecd"}]}{"registration_ids":["APAxxxea-Q0s5pbFZHpSu4BfKdabxxxxxxxxWjPGItVSc54U6_t7WsJme5Z5UjYldhry66rTHk95CUcRR7m2iAtfvPgTklbWlHn4YiDZi1Qxxxxxxxg9iz5jKMPiulvIQTTM5F16THVjw"],"data":{"message":"New content available!"}}
But I never receive a push in my device. I've been following tutorials form google and also form StackOverflow answers, but I'm still very noob in android and I'm sure there is something wrong in my code and I can't figure out what it is, any help would be greatly appreciated.
main activity:
package com.example.alfredo.webapp;
import android.app.Activity;
import android.app.IntentService;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.SystemClock;
import android.support.v4.app.NotificationCompat;
import android.support.v4.content.WakefulBroadcastReceiver;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MenuItem;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.TextView;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.gcm.GoogleCloudMessaging;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.atomic.AtomicInteger;
public class MainActivity extends ActionBarActivity {
public static final String PROPERTY_REG_ID = "registration_id";
private static final String PROPERTY_APP_VERSION = "appVersion";
private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;
String SENDER_ID = "xxxxxxxxxxxx";
/**
* Tag used on log messages.
*/
static final String TAG = "GCMDemo";
private WebView myWebView = null;
TextView mDisplay;
GoogleCloudMessaging gcm;
AtomicInteger msgId = new AtomicInteger();
SharedPreferences prefs;
Context context;
String regid;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "hola coño");
setContentView(R.layout.activity_main);
//initialize variables
context = getApplicationContext();
gcm = GoogleCloudMessaging.getInstance(this);
prefs = getPreferences(0);
mDisplay = new TextView(getApplicationContext());
// web view
this.myWebView = (WebView) findViewById(R.id.webview);
myWebView.setWebViewClient(new WebViewClient());
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
myWebView.loadUrl("http://mongini.net/guiasdelsur");
//remove shared prefs
/*
SharedPreferences prefs = getGCMPreferences(context);
SharedPreferences.Editor edit = prefs.edit();
edit.clear();
edit.commit();
*/
/*
SharedPreferences clear_cache = getSharedPreferences("registration_id", MODE_PRIVATE);
SharedPreferences.Editor edit = clear_cache.edit();
edit.clear();
edit.commit();
*/
// Check device for Play Services APK. If check succeeds, proceed with
// GCM registration.
if (checkPlayServices()) {
gcm = GoogleCloudMessaging.getInstance(this);
regid = getRegistrationId(context);
if (regid.isEmpty()) {
registerInBackground();
Log.i(TAG,"ok");
}
} else {
Log.i(TAG, "No valid Google Play Services APK found.");
}
}
// You need to do the Play Services APK check here too.
#Override
protected void onResume() {
super.onResume();
checkPlayServices();
}
/**
* Check the device to make sure it has the Google Play Services APK. If
* it doesn't, display a dialog that allows users to download the APK from
* the Google Play Store or enable it in the device's system settings.
*/
private boolean checkPlayServices() {
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (resultCode != ConnectionResult.SUCCESS) {
if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
GooglePlayServicesUtil.getErrorDialog(resultCode, this,
PLAY_SERVICES_RESOLUTION_REQUEST).show();
} else {
Log.d(TAG, "This device is not supported.");
finish();
}
return false;
}
return true;
}
/**
* Gets the current registration ID for application on GCM service.
* <p>
* If result is empty, the app needs to register.
*
* #return registration ID, or empty string if there is no existing
* registration ID.
*/
private String getRegistrationId(Context context) {
final SharedPreferences prefs = getGCMPreferences(context);
String registrationId = prefs.getString(PROPERTY_REG_ID, "");
if (registrationId.isEmpty()) {
Log.i(TAG, "Registration not found.");
return "";
}
// Check if app was updated; if so, it must clear the registration ID
// since the existing registration ID is not guaranteed to work with
// the new app version.
int registeredVersion = prefs.getInt(PROPERTY_APP_VERSION, Integer.MIN_VALUE);
int currentVersion = getAppVersion(context);
if (registeredVersion != currentVersion) {
Log.i(TAG, "App version changed.");
return "";
}
return registrationId;
}
/**
* #return Application's {#code SharedPreferences}.
*/
private SharedPreferences getGCMPreferences(Context context) {
// This sample app persists the registration ID in shared preferences, but
// how you store the registration ID in your app is up to you.
return getSharedPreferences(MainActivity.class.getSimpleName(),
Context.MODE_PRIVATE);
}
/**
* #return Application's version code from the {#code PackageManager}.
*/
private static int getAppVersion(Context context) {
try {
PackageInfo packageInfo = context.getPackageManager()
.getPackageInfo(context.getPackageName(), 0);
return packageInfo.versionCode;
} catch (PackageManager.NameNotFoundException e) {
// should never happen
throw new RuntimeException("Could not get package name: " + e);
}
}
/**
* Registers the application with GCM servers asynchronously.
* <p>
* Stores the registration ID and app versionCode in the application's
* shared preferences. com.example.alfredo.webapp.MainActivity
*/
private void registerInBackground() {
new AsyncTask<Void,Void,String>() {
#Override
protected String doInBackground(Void... params) {
String msg = "";
try {
regid = gcm.register(SENDER_ID);
msg = "Device registered, registration id=" + regid;
// You should send the registration ID to your server over HTTP,
// so it can use GCM/HTTP or CCS to send messages to your app.
sendRegistrationIdToBackend();
// Save the regid for future use - no need to register again.
SharedPreferences.Editor editor = prefs.edit();
editor.putString(PROPERTY_REG_ID, regid);
editor.commit();
} catch (IOException ex) {
msg = "Error :" + ex.getMessage();
}
return msg;
}
// Once registration is done, display the registration status
// string in the Activity's UI.
#Override
protected void onPostExecute(String msg) {
mDisplay.append(msg + "\n");
}
}.execute();
}
private String readStream(InputStream is) {
try {
ByteArrayOutputStream bo = new ByteArrayOutputStream();
int i = is.read();
while(i != -1) {
bo.write(i);
i = is.read();
}
return bo.toString();
} catch (IOException e) {
return "";
}
}
/**
* Sends the registration ID to your server over HTTP, so it can use GCM/HTTP
* or CCS to send messages to your app. Not needed for this demo since the
* device sends upstream messages to a server that echoes back the message
* using the 'from' address in the message.
*/
private void sendRegistrationIdToBackend() {
// Your implementation here.
HttpURLConnection urlConnection = null;
try {
URL url = new URL("http://www.mongini.net/android.php?host=localhost&dbname=bdapp&user=user&pass=pass&idPush="+regid);
urlConnection = (HttpURLConnection) url.openConnection();
/** Connecting to url */
urlConnection.connect();
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
readStream(in);
}catch(Exception e){
Log.d("Exception url ", e.toString());
}finally {
urlConnection.disconnect();
}
}
/**
* Stores the registration ID and app versionCode in the application's
* {#code SharedPreferences}.
*
* #param context application's context.
* #param regId registration ID
*/
//aqui peta
private void storeRegistrationId(Context context, String regId) {
final SharedPreferences prefs = getGCMPreferences(context);
int appVersion = getAppVersion(context);
Log.i(TAG, "Saving regId on app version " + appVersion);
SharedPreferences.Editor editor = prefs.edit();
editor.putString(PROPERTY_REG_ID, regId);
editor.putInt(PROPERTY_APP_VERSION, appVersion);
editor.commit();
}
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());
// Start the service, keeping the device awake while it is launching.
startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}
}
public class GcmIntentService extends IntentService {
public static final int NOTIFICATION_ID = 1;
private NotificationManager mNotificationManager;
NotificationCompat.Builder builder;
public GcmIntentService() {
super("GcmIntentService");
}
#Override
protected void onHandleIntent(Intent intent) {
Bundle extras = intent.getExtras();
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
// The getMessageType() intent parameter must be the intent you received
// in your BroadcastReceiver.
String messageType = gcm.getMessageType(intent);
if (!extras.isEmpty()) { // has effect of unparcelling Bundle
/*
* Filter messages based on message type. Since it is likely that GCM
* will be extended in the future with new message types, just ignore
* any message types you're not interested in, or that you don't
* recognize.
*/
if (GoogleCloudMessaging.
MESSAGE_TYPE_SEND_ERROR.equals(messageType)) {
sendNotification("Send error: " + extras.toString());
} else if (GoogleCloudMessaging.
MESSAGE_TYPE_DELETED.equals(messageType)) {
sendNotification("Deleted messages on server: " +
extras.toString());
// If it's a regular GCM message, do some work.
} else if (GoogleCloudMessaging.
MESSAGE_TYPE_MESSAGE.equals(messageType)) {
// This loop represents the service doing some work.
for (int i=0; i<5; i++) {
Log.i(TAG, "Working... " + (i+1)
+ "/5 # " + SystemClock.elapsedRealtime());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
}
Log.i(TAG, "Completed work # " + SystemClock.elapsedRealtime());
// Post notification of received message.
sendNotification("Received: " + extras.toString());
Log.i(TAG, "Received: " + extras.toString());
}
}
// Release the wake lock provided by the WakefulBroadcastReceiver.
GcmBroadcastReceiver.completeWakefulIntent(intent);
}
// Put the message into a notification and post it.
// This is just one simple example of what you might choose to do with
// a GCM message.
private void sendNotification(String msg) {
mNotificationManager = (NotificationManager)
this.getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
new Intent(this, MainActivity.class), 0);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
//.setSmallIcon(R.drawable.ic_stat_gcm)
.setContentTitle("GCM Notification")
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(msg))
.setContentText(msg);
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
}
}
//back device button
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK) && this.myWebView.canGoBack()) {
this.myWebView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
Manifest file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.alfredo.webapp" >
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission android:name="com.example.alfredo.webapp.permission.C2D_MESSAGE"
android:protectionLevel="signature"/>
<uses-permission android:name="com.example.alfredo.webapp.permission.C2D_MESSAGE"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<receiver
android:name=".MainActivity$GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
</receiver>
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="com.example.alfredo.webapp" />
</intent-filter>
</activity>
<service android:name=".MainActivity$GcmIntentService" />
</application>
</manifest>
build gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 22
buildToolsVersion "22.0.1"
defaultConfig {
applicationId "com.example.alfredo.webapp"
minSdkVersion 10
targetSdkVersion 22
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.0.0'
compile 'com.google.android.gms:play-services:7.0.0'
}
It will be hard to find the real solution without fixing your BroadcastReceiver implementation first.
It looks like you are following a deprecated sample. In the manifest, you no longer need the com.google.android.c2dm.intent.REGISTRATION action. Also, your receiver tag/entry should be outside the activity tag, and it should have an intent filter (your intent filter is outside the receiver tag).
Hope this leads you to a solution. You might want to follow this sample code instead.
i am new with android SMS and I am trying to study it. So i am trying to make an android app that always works on the background, and when I receive sms with the content of "hello"(somebody sending "hello" to my phone by SMS) a music will play.
I searched all over the internet, and I built a project that worked on the AVD, but when I tested it on my phone it didn't work:
import info.kfsoft.android.R.raw;
import android.app.Notification;
import android.app.NotificationManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.telephony.SmsMessage;
import android.widget.TextView;
import android.widget.Toast;
public class SMSReceiver extends BroadcastReceiver
{
MediaPlayer ourSong;
//static final int uniqueID=12345;
TextView display;
public void onReceive(Context context, Intent intent)
{
NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
ourSong = MediaPlayer.create(context, R.raw.music2);
Bundle myBundle = intent.getExtras();
SmsMessage [] messages = null;
String strMessage = "";
if (myBundle != null)
{
Object [] pdus = (Object[]) myBundle.get("pdus");
messages = new SmsMessage[pdus.length];
for (int i = 0; i < messages.length; i++)
{
messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
// strMessage += "SMS From the king him self: " + messages[i].getOriginatingAddress();
// strMessage += " : ";
strMessage += messages[i].getMessageBody();
// strMessage += "\n";
}
//max volume
AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
am.setStreamVolume(AudioManager.STREAM_MUSIC,am.getStreamMaxVolume(AudioManager.STREAM_MUSIC),0);
Toast.makeText(context, strMessage, Toast.LENGTH_SHORT).show();
// Notification n=new Notification(android.R.drawable.)
// nm.notify(uniqueID,n);
ourSong.start();
}
}
public void a(){
}
}
THX.
Maybe it's your intent priority too low and system-installed SMSApp receives a message before your application. Try adding priority="999"
<receiver android:name="OnAlarmReceiver">
<intent-filter android:priority="999">
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
Another trick is not register SMS_RECEIVED in a AndroidManifest.xml file but programmatically in an application code. Here is an example where I actually register multiple events to a same broadcastreceiver.
broadcastReceiver = new EventReceiver();
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction("android.provider.Telephony.SMS_RECEIVED");
filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY-1);
registerReceiver(broadcastReceiver, filter);
I have a widget with 1 image view and 1 text view.
I want to change image on click. Consider following code doesn't catch touch event
package com.sigrlami.rixvpn.widget;
import java.util.Random;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.RemoteViews;
import com.sigrlami.rixvpn.R;
public class VpnWidgetProvider extends AppWidgetProvider {
private boolean currentStatus = false;
// log tag
private static final String LOG = "com.sigrlami.rixvpn.widget.VpnWidgetProvider";
//public static final String CLICK = "com.sigrlami.rixvpn.CLICK";
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
// Get all ids
ComponentName thisWidget = new ComponentName(context, VpnWidgetProvider.class);
int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
for (int widgetId : allWidgetIds) {
// Create some random data
int number = (new Random().nextInt(100));
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.vpn_widget);
Log.w("WidgetExample", String.valueOf(number));
// Set the text
remoteViews.setTextViewText(R.id.layout_vpn_widget_tv_Check, String.valueOf(number));
// Register an onClickListener
Intent intent = new Intent(context, VpnWidgetProvider.class);
intent.setAction(appWidgetManager.ACTION_APPWIDGET_UPDATE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
remoteViews.setOnClickPendingIntent(R.id.layout_vpn_widget_iv_Check, pendingIntent);
if (currentStatus = false) {
remoteViews.setImageViewResource(R.id.layout_vpn_widget_iv_Check, R.drawable.on);
} else {
remoteViews.setImageViewResource(R.id.layout_vpn_widget_iv_Check, R.drawable.off);
}
appWidgetManager.updateAppWidget(widgetId, remoteViews);
}
}
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
if (currentStatus == false) {
currentStatus = true;
} else {
currentStatus = false;
}
}
super.onReceive(context, intent);
}
}
Looking to this part through debugger shows nothing strange, but when I change to getActivity() it shows that I'm trying to start a activity that does not exist. I see that something is going on, but this is useless to me.
// Register an onClickListener
Intent intent = new Intent(context, VpnWidgetProvider.class);
intent.setAction(appWidgetManager.ACTION_APPWIDGET_UPDATE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
remoteViews.setOnClickPendingIntent(R.id.layout_vpn_widget_iv_Check, pendingIntent);
But it works 1 time when app deployed to device.
Any suggestions what I have done wrong?
For handling click in AppWidgetProvider you need to use custom broadcast reciver as:
<receiver android:name="VpnWidgetProvider"
android:label="#string/widget_title" android:exported="false" android:icon="#drawable/volume">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="com.xxxx.xxxx.VpnWidgetProvider.ACTION_WIDGET_REFRESH"/>
<action android:name="android.appwidget.action.APPWIDGET_DELETED"/>
<action android:name="android.media.RINGER_MODE_CHANGED"/>
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="#xml/widget_info" />
and in AppWidgetProvider class:
public class VpnWidgetProvider extends AppWidgetProvider {
public static String ACTION_WIDGET_REFRESH = "ActionReceiverRefresh";
//your code here...
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
//you code here...
Intent intent = new Intent(context, VpnWidgetProvider.class);
intent.setAction(appWidgetManager.ACTION_WIDGET_REFRESH);//get action here
//you code here...
see this full working example for handling onclick on home Screen AppWidget:
Silenttoggle Home Screen Widget
I am new to android development.I am developing small android application. In my application I want to retrieve newly coming sms and display this message to user. My code looks like
// HellowordActivity.java
package com.example.helloword;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.app.Activity;
import android.os.Bundle;
import android.telephony.SmsMessage;
import android.util.Log;
import android.widget.Toast;
public class HellowordActivity extends BroadcastReceiver
{
public void onReceive(Context context, Intent intent)
{
Bundle myBundle = intent.getExtras();
SmsMessage [] messages = null;
String strMessage = "";
if (myBundle != null)
{
Object [] pdus = (Object[]) myBundle.get("pdus");
messages = new SmsMessage[pdus.length];
for (int i = 0; i < messages.length; i++)
{
messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
strMessage += "SMS From: " + messages[i].getOriginatingAddress();
strMessage += " : ";
strMessage += messages[i].getMessageBody().toString();
strMessage += "\n";
}
// Toast.makeText(context, strMessage, Toast.LENGTH_SHORT).show();
Intent _intent = new Intent(context, PopupActivity.class);
_intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
_intent.putExtra("strMessage", strMessage);
startActivity(_intent);
}
}
}
I added receiver and permission in Android Manifest.xml
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
<receiver android:name=".HellowordActivity" >
<intent-filter >
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
<activity android:name=".PopupActivity" android:launchMode="singleTop" />
I am not doing any thing in layout part.What I want as an output when new message will come;
message text display to user with simple popup.
Need Help.. Thank you...
Try this it works for me you will get a toast shown to you with the content of the message received:
package com.example.a;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsMessage;
import android.util.Log;
import android.widget.Toast;
public class SMSBroadcastReceiver extends BroadcastReceiver {
private static final String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
private static final String TAG = "SMSBroadcastReceiver";
#Override
public void onReceive(Context context, Intent intent) {
Log.i(TAG, "Intent recieved: " + intent.getAction());
if (intent.getAction().equals(SMS_RECEIVED)) {
Bundle bundle = intent.getExtras();
if (bundle != null) {
Object[] pdus = (Object[])bundle.get("pdus");
final SmsMessage[] messages = new SmsMessage[pdus.length];
for (int i = 0; i < pdus.length; i++) {
messages[i] = SmsMessage.createFromPdu((byte[])pdus[i]);
}
if (messages.length > -1) {
Toast.makeText(context, "Message recieved: " + messages[0].getMessageBody(), 7000).show();
}
}
}
}
}
The AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.a"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
<uses-permission android:name="android.permission.HARDWARE_TEST"/>
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<receiver android:name=".SMSBroadcastReceiver" >
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" >
</action>
</intent-filter>
</receiver>
</application>
</manifest>
Use DDMS to send sms to your emulator via Telnet
if you want to show an popup when SMS is Recived then you will need to Create an Activity with android:launchMode="singleTop" as:
In manifast declare Activity as:
<activity android:name=".PopupActivity" android:launchMode="singleTop" />
From HellowordActivity BroadcastReceiver start Activity as:
Intent intent = new Intent(context, PopupActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent .putExtra("strMessage", strMessage);
context.startActivity(intent);
And in your PopupActivity.class:
public class PopupActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// The activity is being created.
Intent intent= getIntent();//get message here
String strMessage = intent.getStringExtra("strMessage");
//NOW YOU CAN SHOW THIS MESSAGE IN POPUP
}
#Override
protected void onStop() {
super.onStop();
this.finish();
// The activity is no longer visible (it is now "stopped")
}
You can also checkout these Smspopup apps source code:
android-smspopup
sms-enhancer