I want to use GCM. I tried with following in the client side:
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.test" android:installLocation="preferExternal" android:versionCode="1" android:versionName="1.0">
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="16" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.VIBRATE" />
<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.test.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="com.example.test.permission.C2D_MESSAGE" />
<application android:icon="#drawable/ic_launcher" android:label="#string/app_name" >
<activity android:screenOrientation="portrait"
android:name=".MainActivity"
android:label="#string/app_name"
android:theme="#android:style/Theme.NoTitleBar.Fullscreen" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name="com.google.android.gcm.GCMBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.example.test" />
</intent-filter>
</receiver>
<service android:name=".GCMIntentService" android:enabled="true" />
</application>
</manifest>
Activity:
package com.example.test;
import com.google.android.gcm.GCMRegistrar;
import android.os.Bundle;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.Intent;
import android.util.Log;
import android.view.Menu;
import android.view.WindowManager;
import android.widget.Toast;
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gcmRelated();
}
private void gcmRelated() {
GCMRegistrar.checkDevice(this);
GCMRegistrar.checkManifest(this);
final String regId = GCMRegistrar.getRegistrationId(this);
Toast.makeText(this, regId, 10000).show();
if (regId.equals("")) {
GCMRegistrar.register(this, "609612932495");
} else {
Log.v("Register", "Already registered");
}
}
}
GCMIntentService.java:
package com.example.test;
import com.google.android.gcm.GCMBaseIntentService;
import com.google.android.gcm.GCMRegistrar;
import android.content.Context;
import android.content.Intent;
import android.os.PowerManager;
import java.util.logging.Logger;
public class GCMIntentService extends GCMBaseIntentService
{
private static PowerManager.WakeLock sWakeLock;
private static final Object LOCK = GCMIntentService.class;
private static final String GCM_SENDER_ID = "609612932495";
private static final String GCM_INTENT_FILTER = "com.example.test.GCM_MESSAGE";
private static final String MESSAGE_TYPE = "Type";
private static final String MESSAGE_CONTENT = "Body";
private static Logger log = Logger.getLogger(GCMIntentService.class.getName());
public GCMIntentService()
{
super(GCM_SENDER_ID);
}
static void runIntentInService(Context context,Intent intent)
{
synchronized(LOCK)
{
if (sWakeLock == null)
{
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
sWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,"sc_wakelock");
}
}
sWakeLock.acquire();
intent.setClassName(context,GCMIntentService.class.getName());
context.startService(intent);
}
#Override protected void onRegistered(Context context,String registrationId)
{
log.warning("From GCMIntentService: Device successfully registered as "+registrationId);
}
#Override protected void onUnregistered(Context context,String registrationId)
{
log.warning("From GCMIntentService: Device successfully unregistered");
}
#Override protected void onMessage(Context context,Intent messageIntent)
{
log.warning("From GCMIntentService: Game update notice received");
}
#Override protected void onDeletedMessages(Context context,int total)
{
log.warning("From GCMIntentService: Server deleted "+Integer.toString(total)+" pending messages");
}
#Override public void onError(Context context,String errorId)
{
log.warning("From GCMIntentService: Error "+errorId);
}
#Override protected boolean onRecoverableError(Context context,String errorId)
{
log.warning("From GCMIntentService: Recoverable error "+errorId);
return(super.onRecoverableError(context,errorId));
}
}
It's showing no error. GCMRegistrar.getRegistrationId(this) is always returning " "(empty string). So, It always tries to register and I never got registerId.
Anything to be done?
Also, While implementing the server side code, Do I need to send this register Id and save all the id's in a database and send them?
public class GCMIntentService extends GCMBaseIntentService {
#SuppressWarnings("unused")
private final String TAG = "GCMIntentService";
public GCMIntentService() {
super("GCM_ID");
}
/**
* Issues a notification to inform the user that server has sent a message.
*/
public void generateNotification(Context context, String message) {
long when = System.currentTimeMillis();
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(R.drawable.ic_launcher, message, when);
String title = context.getString(R.string.app_name);
Intent notificationIntent = new Intent(context, SamplePushActivity.class);
PendingIntent intent = PendingIntent.getActivity(context, 0, notificationIntent, android.content.Intent.FLAG_ACTIVITY_NEW_TASK);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
notification.setLatestEventInfo(context, title, message, intent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.defaults |= Notification.DEFAULT_SOUND | Notification.DEFAULT_LIGHTS;
notificationManager.notify(0, notification);
}
#Override
protected void onError(Context arg0, String arg1) {
}
#Override
protected void onMessage(Context arg0, Intent arg1) {
Resources res = getResources();
Log.d("GCM", "RECIEVED A MESSAGE");
// Get the data from intent and send to notificaion bar
System.out.println("MEssage Recieved :" + arg1.getStringExtra("message"));
System.out.println("Data Recieved :" + arg1.getExtras().getString("collapse_key"));
// generateNotification(arg0, arg1.getStringExtra("state"));
// generateNotification(arg0, arg1.getStringExtra("message"));
generateNotification(arg0, res.getString(R.string.assignment_new, "arg1", "arg2"));
// String notifyMessage = arg1.getStringExtra("collapse_key");
// if
// (arg1.getStringExtra("collapse_key").equalsIgnoreCase("NOTIFICATION_ASSIGNMENT"))
// {
// generateNotification(arg0, arg1.getStringExtra("message"));
// }
}
#Override
protected void onRegistered(Context arg0, String arg1) {
// TODO Auto-generated method stub
}
#Override
protected void onUnregistered(Context arg0, String arg1) {
// TODO Auto-generated method stub
}
public class SamplePushActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView regNumber = (TextView) findViewById(R.id.textView1);
GCMRegistrar.checkDevice(this);
GCMRegistrar.checkManifest(this);
if (GCMRegistrar.isRegistered(this)) {
Log.d("info", GCMRegistrar.getRegistrationId(this));
}
final String regId = GCMRegistrar.getRegistrationId(this);
regNumber.setText(regId);
if (regId.equals("")) {
// replace this with the project ID
System.out.println("registration ID is " + regId);
GCMRegistrar.register(this, "GCM_ID");
Log.d("info", GCMRegistrar.getRegistrationId(this));
System.out.println("Get Reg ID: " + GCMRegistrar.getRegistrationId(this));
regNumber.setText(regId);
} else {
Log.d("info", "already registered as" + regId);
}
}
<uses-sdk android:minSdkVersion="8" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<permission
android:name="in.android.gcm.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="in.android.gcm.permission.C2D_MESSAGE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:name=".SamplePushActivity"
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="com.google.android.gcm.GCMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="in.android.gcm" />
</intent-filter>
</receiver>
<service android:name=".GCMIntentService" />
</application>
Related
I'm trying to make service that will do something each time phone call is ended. My problem is that service doesn't receive any broadcasts.
I've implemented it like that:
package com.kubasienki.spedycja;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
import android.util.Log;
/**
* Created by kuba on 11/4/2015.
*/
public class FirstService extends Service {
private static String TAG = "kurwa";
final BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(action.equals("android.provider.Telephony.CALL_STATE_IDLE")){
Log.v("kurwa", "skonczono");
}
else if(action.equals(android.telephony.TelephonyManager.ACTION_PHONE_STATE_CHANGED)){
Log.v("kurwa", "???");
}
else {
Log.v("kurwa", "??!!!?");
}
}
};
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
super.onStart(intent, startId);
Log.d(TAG, "FirstService started");
IntentFilter filter = new IntentFilter();
filter.addAction("android.provider.TelephonyManager.CALL_STATE_IDLE");
filter.addAction(android.telephony.TelephonyManager.ACTION_PHONE_STATE_CHANGED);
registerReceiver(receiver, filter);
//this.stopSelf();
}
#Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Log.d(TAG, "FirstService destroyed");
}
}
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.kubasienki.spedycja" >
<uses-permission android:name="android.permission.CALL_PHONE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/Theme.AppCompat.Light.NoActionBar.FullScreen" >
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<activity android:name="com.kubasienki.spedycja.MainActivity"
android:screenOrientation="portrait"
android:configChanges="orientation|keyboardHidden">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".FirstService" ></service>
</application>
</manifest>
And starting service :
startService(new Intent(this, FirstService.class));
Create a broadcast which listen for Call
class CallReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {//do want you want
}
}
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<receiver android:name=".CallReceiver">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
</receiver>
Handling Phone Call Requests the Right Way for Users
Perrmissions were in the wrong place.
I am developing a sample watch face wherein a user would be able to select some color configuration on mobile app triggering changes on wear app watch face.
Here is what I have in mobile app to send configuration:
package com.quicklyjava.templatewatchface;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.wearable.DataApi;
import com.google.android.gms.wearable.PutDataMapRequest;
import com.google.android.gms.wearable.PutDataRequest;
import com.google.android.gms.wearable.Wearable;
/**
* Created by P
*/
public class WearConnection {
private final GoogleApiClient mGoogleApiClient;
private String TAG = "wear.bridge";
public WearConnection(Context context) {
mGoogleApiClient = new GoogleApiClient.Builder(context)
.addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
#Override
public void onConnected(Bundle connectionHint) {
Log.d(TAG, "onConnected: " + connectionHint);
}
#Override
public void onConnectionSuspended(int cause) {
Log.d(TAG, "onConnectionSuspended: " + cause);
}
})
.addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
#Override
public void onConnectionFailed(ConnectionResult result) {
Log.d(TAG, "onConnectionFailed: " + result);
}
})
.addApi(Wearable.API)
.build();
}
public void connect(){
mGoogleApiClient.connect();
}
public void disconnect() {
mGoogleApiClient.disconnect();
}
public void sendColor(String path, int color) {
PutDataMapRequest dataMap = PutDataMapRequest.create(path);
dataMap.getDataMap().putInt("value", color);
PutDataRequest request = dataMap.asPutDataRequest();
PendingResult<DataApi.DataItemResult> pendingResult = Wearable.DataApi.putDataItem(mGoogleApiClient, request);
pendingResult.setResultCallback(new ResultCallback<DataApi.DataItemResult>() {
#Override
public void onResult(DataApi.DataItemResult dataItemResult) {
Log.d("wear", "sent: " + dataItemResult);
}
});
}
}
Here is the manifest for mobile:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.quicklyjava.templatewatchface" >
<uses-permission android:name="com.google.android.permission.PROVIDE_BACKGROUND" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<meta-data android:name="com.google.android.gms.version" android:value="#integer/google_play_services_version" />
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
Here is the listener service I implemented in wear:
package com.quicklyjava.templatewatchface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.preference.PreferenceManager;
import android.util.Log;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.data.FreezableUtils;
import com.google.android.gms.wearable.DataEvent;
import com.google.android.gms.wearable.DataEventBuffer;
import com.google.android.gms.wearable.DataMapItem;
import com.google.android.gms.wearable.Node;
import com.google.android.gms.wearable.Wearable;
import com.google.android.gms.wearable.WearableListenerService;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* Created by P
*/
public class TemplateWatchConfigListenerService extends WearableListenerService {
private static final String TAG = "DataLayerSample";
private SharedPreferences preferences;
// keys for the data map
private String KEY_DOT_COLOR="com.quicklyjava.backgroundcolor";
GoogleApiClient mGoogleApiClient;
#Override
public void onCreate() {
super.onCreate();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Wearable.API)
.build();
mGoogleApiClient.connect();
preferences = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
}
#Override
public void onDataChanged(DataEventBuffer dataEvents) {
LOGD(TAG, "onDataChanged: " + dataEvents);
final List<DataEvent> events = FreezableUtils.freezeIterable(dataEvents);
dataEvents.close();
if(!mGoogleApiClient.isConnected()) {
ConnectionResult connectionResult = mGoogleApiClient.blockingConnect(30, TimeUnit.SECONDS);
if (!connectionResult.isSuccess()) {
Log.e(TAG, "WatchFaceConfigListenerService failed to connect to GoogleApiClient.");
return;
}
}
// Loop through the events and send a message back to the node that created the data item.
for (DataEvent event : events) {
Uri uri = event.getDataItem().getUri();
String path = uri.getPath();
DataMapItem item = DataMapItem.fromDataItem(event.getDataItem());
switch (path) {
case "/backgroundColor":
putIntPreference(KEY_DOT_COLOR, item.getDataMap().getInt("value"));
break;
default:
Log.e("TempWatchList","Default");
}
getBaseContext().sendBroadcast(new Intent("com.quicklyjava.action.config_changed"));
}
}
#Override
public void onPeerConnected(Node peer) {
LOGD(TAG, "onPeerConnected: " + peer);
}
#Override
public void onPeerDisconnected(Node peer) {
LOGD(TAG, "onPeerDisconnected: " + peer);
}
public static void LOGD(final String tag, String message) {
if (Log.isLoggable(tag, Log.DEBUG)) {
Log.d(tag, message);
}
}
private void putIntPreference(String key, int value) {
preferences
.edit()
.putInt(key, value)
.apply();
}
}
Finally here is the wear manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.quicklyjava.templatewatchface" >
<uses-sdk android:minSdkVersion="21"
android:targetSdkVersion="21" />
<uses-feature android:name="android.hardware.type.watch" />
<!-- Required to act as a custom watch face. -->
<uses-permission android:name="com.google.android.permission.PROVIDE_BACKGROUND" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<service
android:name=".TemplateWatchService"
android:label="#string/template_name"
android:permission="android.permission.BIND_WALLPAPER" >
<meta-data
android:name="android.service.wallpaper"
android:resource="#xml/watch_face" />
<meta-data
android:name="com.google.android.wearable.watchface.preview"
android:resource="#drawable/preview_digital" />
<meta-data
android:name="com.google.android.wearable.watchface.preview_circular"
android:resource="#drawable/preview_digital_circular" />
<intent-filter>
<action android:name="android.service.wallpaper.WallpaperService" />
<category android:name="com.google.android.wearable.watchface.category.WATCH_FACE" />
</intent-filter>
</service>
<service android:name=".TemplateWatchConfigListenerService" >
<intent-filter>
<action android:name="com.google.android.gms.wearable.BIND_LISTENER" />
</intent-filter>
</service>
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
</application>
The onDataChanged method is not getting triggered when the sendColor method in mobile app is called. Is there anything I am missing?
add a key-value in the data item map
map.put("system", System.currentmillions())
and send again
yeah, you are missing some important meta-data tags
In wear manifest, add these tag to the WatchFaceService's service tag:
<meta-data <!-- Companion config -->
android:name="com.google.android.wearable.watchface.companionConfigurationAction"
android:value="com.example.package.CONFIG_FACE" />
<meta-data <!-- wear config -->
android:name="com.google.android.wearable.watchface.wearableConfigurationAction"
android:value="com.example.package.CONFIG_FACE" />
And in your Companion manifest , just add only these lines to the CompanionConfigActivity's activity tag :
<intent-filter>
<action android:name="com.example.package.CONFIG_FACE" />
<category android:name="com.google.android.wearable.watchface.category.COMPANION_CONFIGURATION" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
The code :
com.example.package.CONFIG_FACE
must be same in both the manifests.
i have a string in my service, and i want to send it to fragment. But it seems onReceive() method on my BroadcastReceiver never called, and i just can't figured out why. Thanks for answers.
My Service Class
public class Servis extends Service {
static final String MAP = "MyService";
static final String USERID = "";
public static final String FILEPATH = "filepath";
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
System.out.println("starting service");
Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
String id = intent.getStringExtra("UserID");
System.out.println(id);
Intent intent1 = new Intent(MAP);
intent1.putExtra(USERID, id);
sendBroadcast(intent1);
return START_REDELIVER_INTENT;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
Toast.makeText(this, "My Service Created", Toast.LENGTH_LONG).show();
Log.d(MAP, "onCreate");
}
#Override
public void onDestroy() {
Toast.makeText(this, "My Service Stopped", Toast.LENGTH_LONG).show();
Log.d(MAP, "onDestroy");
}
#Override
public void onStart(Intent intent, int startid) {
Toast.makeText(this, "My Service Started", Toast.LENGTH_LONG).show();
Log.d(MAP, "onStart");
}
}
My Fragment Class
package com.example.mobilproje;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.widget.Toast;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
public class MapFragment extends FragmentActivity{
private GoogleMap googleHarita;
private BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
handleResult(bundle);
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.map_fragment);
registerReceiver(receiver, new IntentFilter(
Servis.MAP));
if (googleHarita == null) {
googleHarita = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.haritafragment))
.getMap();
if (googleHarita != null)
LatLng EvKoordinat = new LatLng(40.7994211,29.9517352);
googleHarita.addMarker(new MarkerOptions().position(EvKoordinat).title("Ev"));
googleHarita.moveCamera(CameraUpdateFactory.newLatLngZoom(EvKoordinat, 13));
}
}
}
#Override
public void onResume() {
registerReceiver(receiver, new IntentFilter(
Servis.MAP));
}
private void handleResult(Bundle bundle) {
if (bundle != null) {
String string = bundle.getString(Servis.USERID);
System.out.println("string");
}
}
}
AndroidManifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.mobilproje"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="13"
android:targetSdkVersion="23" />
<uses-permission android:name="android.permission.NFC" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-feature
android:glEsVersion="0x00020000"
android:required="true" />
<application
android:allowBackup="true"
android:icon="#drawable/nfc"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:theme="#style/mytheme"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.TECH_DISCOVERED" />
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<action android:name="android.nfc.action.TAG_DISCOVERED" />
</intent-filter>
<meta-data
android:name="android.nfc.action.TECH_DISCOVERED"
android:resource="#xml/nfc_tech_filter" />
</activity>
<activity
android:name=".MapFragment"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="AIzaSyCgPPczPpQA_00_v-nTux_WuGuaO9egUpc" />
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<service android:enabled="true" android:name=".Servis" android:process=":localservice"/>
</application>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
</manifest>
I can not find answer for this problem.
I am building some Android application based on sms services and
I found callback very difficult.
I want/need to call my primary application class MainActivity from inside function onReceive (class SMSReceiver).
Toast works perfectly but any attempt to call public void OnSmsReceived() (class MainActivity) is unsuccessful.
// Main class
public class MainActivity extends Activity {
public void OnSmsReceived() {
System.out.println(TAG + ": OnSmsReceived " + "OK ");
}
/* more not important at this moment code bellow */
}
// Brodcast class
public class SMSReceiver extends BroadcastReceiver {
private static final String TAG = "SMSReceiver";
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "SMS received.", Toast.LENGTH_LONG).show();
System.out.println(TAG + ": " + "onReceive");
//How to call MainActivity form here?
}
}
Ok, I finaly made that working:
This is really working code
Thank you for intent ...
//Android Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="sms.pack.sms201"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="8" />
<uses-permission android:name="android.permission.BROADCAST_SMS"/>
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="sms.pack.sms201.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="sms.pack.sms201.SMSReceiver"
android:enabled="true"
android:exported="true"
android:permission="android.permission.BROADCAST_SMS">
<intent-filter android:priority="1000">
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
</application>
</manifest>
//SMSReceiver class
public class SMSReceiver extends BroadcastReceiver {
private static final String TAG = "SMSReceiver";
public static String Test = "empty";
#Override
public void onReceive(Context context, Intent intent) {
Log.v(TAG, "onReceive");
Toast.makeText(context, "SMS received.", Toast.LENGTH_LONG).show();
Bundle bundle = intent.getExtras();
if( bundle != null) {
Log.v(TAG, "onReceive.bundle != null");
Test = String.valueOf(bundle.size());
}
Intent callingIntent = new Intent(context, MainActivity.class);
callingIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
callingIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
String value = "Extra val=" + Test;
callingIntent.putExtra("SMSR", value);
context.startActivity(callingIntent);
}
}
//MainActivity class
public class MainActivity extends Activity {
private static final String TAG = "MainActivity";
TextView tvGenLog;
protected void appendGenLog(String txt) {
txt = tvGenLog.getText() + txt + "\r\n";
tvGenLog.setText(txt);
}
private String memberFieldString;
#Override
protected void onNewIntent(Intent intent) {
appendGenLog(TAG + ".onNewIntent");
memberFieldString = intent.getStringExtra("SMSR");
appendGenLog("memberFieldString=" + memberFieldString);
appendGenLog("Take data from SMSReceiver,");
appendGenLog("SMSR=" + SMSReceiver.Test);
super.onNewIntent(intent);
} // End of onNewIntent(Intent intent)
#Override
protected void onResume() {
super.onResume();
//appendGenLog(TAG + ".onResume");
if (getIntent()!=null && getIntent().getExtras()!=null) {
appendGenLog(TAG + ".onResume" + ":" + getIntent().getExtras().getString("SMSR"));
}
else {
appendGenLog(TAG + ".onResume" + ": null");
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.v(TAG, ".onCreate");
tvGenLog = (TextView) findViewById(R.id.tvGenLog);
appendGenLog(TAG + " Created");
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
use context in the onReceive Method and call context.startActivity(context , yourActivity.class);
you can't use context.startActivity(context , MainActivity.class);
but you can choose below method to resolve this issue:
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
context.startActivity(intent, bundle)
I experimented lots of approaches.
I did not say but it is for targetSdkVersion="8"
and some of those functions you gave me did not work on this old system
I could not find working way with use of context and intent. This always caused crash.
I found way with static fields and function in MainActivity,even that works and print something, it crushed after that....
After all this works for me very well.
Of course it is draft but this allow to work with main class.
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="sms.pack.sms0"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="8" />
<uses-permission android:name="android.permission.BROADCAST_SMS"/>
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="sms.pack.sms0.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">sms0</string>
<string name="action_settings">Settings</string>
<string name="sGenInfo">GenInfo</string>
</resources>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res/sms.pack.sms0"
android:id="#layout/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/tvGenInfo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/sGenInfo" />
</LinearLayout>
MainActivity.java
package sms.pack.sms0;
import android.util.Log;
import android.os.Bundle;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.view.Menu;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
private static final String TAG = "MainActivity";
private static final String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
TextView tvGenInfo;
public void appendGenInfo(String txt) {
Log.v(TAG, "genLog, txt=" + txt);
txt = tvGenInfo.getText() + txt + "\r\n";
tvGenInfo.setText(txt);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.v(TAG, "onCreate");
tvGenInfo = (TextView) findViewById(R.id.tvGenInfo);
IntentFilter filter = new IntentFilter(Intent.ACTION_DEFAULT);
filter.addAction(SMS_RECEIVED);
filter.setPriority(1000);
this.registerReceiver(this.smsReceiver, filter);
appendGenInfo("Created");
}
private BroadcastReceiver smsReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.v(TAG, "smsReceiver.onReceive, " + "");
Toast.makeText(context, "smsReceiver.onReceive, " + "", Toast.LENGTH_SHORT).show();
System.out.println(TAG + ", smsReceiver.onReceive, " + "");
Bundle bundle = intent.getExtras();
if( bundle != null) {
System.out.println(TAG + ", smsReceiver.onReceive.bundle, size=" + bundle.size());
appendGenInfo(TAG + ", smsReceiver.onReceive.bundle, " + "bundle.size=" + bundle.size());//this works
}
}
};
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
I want to start my app when a user press the power button. I m following This code
but its not showing any Log and toast.
here is my complete code.
MyReceiver.java
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.Toast;
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Log.v("onReceive", "Power button is pressed.");
Toast.makeText(context, "power button clicked", Toast.LENGTH_LONG)
.show();
// perform what you want here
}
}
menifest File
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.powerbuttontest"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.powerbuttontest.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=".MyReceiver" >
<intent-filter>
<action android:name="android.intent.action.SCREEN_OFF" >
</action>
<action android:name="android.intent.action.SCREEN_ON" >
</action>
<action android:name="android.intent.action.ACTION_POWER_CONNECTED" >
</action>
<action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" >
</action>
<action android:name="android.intent.action.ACTION_SHUTDOWN" >
</action>
</intent-filter>
</receiver>
</application>
</manifest>
MainActivity.java
package com.example.powerbuttontest;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
I think i m committing a mistake in my menifest file. please have a look on this. thanks.
First, unlike other broad casted intents, for Intent.ACTION_SCREEN_OFF and Intent.ACTION_SCREEN_ON you CANNOT declare them in your Android Manifest! so You need to make a service which will keep on running like this
public static class UpdateService extends Service {
#Override
public void onCreate() {
super.onCreate();
// register receiver that handles screen on and screen off logic
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
BroadcastReceiver mReceiver = new Receiver();
registerReceiver(mReceiver, filter);
}
#Override
public void onStart(Intent intent, int startId) {
boolean screenOn = intent.getBooleanExtra("screen_state", false);
if (!screenOn) {
// your code
} else {
// your code
}
}
}
and your receiver can be something
public class Receiver extends BroadcastReceiver {
private boolean screenOff;
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
screenOff = true;
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
screenOff = false;
}
Intent i = new Intent(context, UpdateService.class);
i.putExtra("screen_state", screenOff);
context.startService(i);
}
}
Here is my complete code. Hope this helps. I was basically making a look screen app. This will disable your default lock screen. and on power button press it will start a service and runs to look for power button press event.
Layout.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<Button
android:id="#+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#+id/toggleButton1"
android:layout_marginTop="72dp"
android:enabled="false"
android:text="Settings" />
<ToggleButton
android:id="#+id/toggleButton1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginTop="72dp"
android:checked="true"
android:textOff="Disable"
android:textOn="Enable" />
</RelativeLayout>
MainActivity.java
package com.example.powerbuttontest;
import android.app.Activity;
import android.app.KeyguardManager;
import android.app.KeyguardManager.KeyguardLock;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
import android.widget.ToggleButton;
public class MainActivity extends Activity {
ToggleButton btnToggleLock;
Button btnMisc;
Toast toast;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnMisc = (Button) findViewById(R.id.button1);
btnToggleLock = (ToggleButton) findViewById(R.id.toggleButton1);
toast = Toast.makeText(getApplicationContext(), "", Toast.LENGTH_SHORT);
btnToggleLock.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (btnToggleLock.isChecked()) {
toast.cancel();
toast.setText("Unlocked");
toast.show();
Log.i("Unlocked", "If");
Context context = getApplicationContext();
KeyguardManager _guard = (KeyguardManager) context
.getSystemService(Context.KEYGUARD_SERVICE);
KeyguardLock _keyguardLock = _guard
.newKeyguardLock("KeyguardLockWrapper");
_keyguardLock.disableKeyguard();
MainActivity.this.startService(new Intent(
MainActivity.this, UpdateService.class));
} else {
toast.cancel();
toast.setText("Locked");
toast.show();
Context context = getApplicationContext();
KeyguardManager _guard = (KeyguardManager) context
.getSystemService(Context.KEYGUARD_SERVICE);
KeyguardLock _keyguardLock = _guard
.newKeyguardLock("KeyguardLockWrapper");
_keyguardLock.reenableKeyguard();
Log.i("Locked", "else");
MainActivity.this.stopService(new Intent(MainActivity.this,
UpdateService.class));
}
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
// TODO Auto-generated method stub
super.onConfigurationChanged(newConfig);
Log.i("onConfigurationChanged", "Called");
}
}
MyReciever.java
package com.example.powerbuttontest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.Toast;
public class MyReceiver extends BroadcastReceiver {
private boolean screenOff;
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
screenOff = true;
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
screenOff = false;
}
Intent i = new Intent(context, UpdateService.class);
i.putExtra("screen_state", screenOff);
context.startService(i);
}
}
UpdateService.java
package com.example.powerbuttontest;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
public class UpdateService extends Service {
BroadcastReceiver mReceiver;
#Override
public void onCreate() {
super.onCreate();
// register receiver that handles screen on and screen off logic
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
mReceiver = new MyReceiver();
registerReceiver(mReceiver, filter);
}
#Override
public void onDestroy() {
unregisterReceiver(mReceiver);
Log.i("onDestroy Reciever", "Called");
super.onDestroy();
}
#Override
public void onStart(Intent intent, int startId) {
boolean screenOn = intent.getBooleanExtra("screen_state", false);
if (!screenOn) {
Log.i("screenON", "Called");
Toast.makeText(getApplicationContext(), "Awake", Toast.LENGTH_LONG)
.show();
} else {
Log.i("screenOFF", "Called");
// Toast.makeText(getApplicationContext(), "Sleep",
// Toast.LENGTH_LONG)
// .show();
}
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
Menifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.powerbuttontest"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<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>
<receiver android:name=".MyReceiver" />
<service android:name=".UpdateService" />
</application>
</manifest>
Here this one is the complete code, which will open your application as soon you presss power button. I am also doing the same project, where i want to open my Application directly after i press power button (turn on).
MainActivity.java
public class MainActivity extends Activity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_switch_power_offon);
startService(new Intent(getApplicationContext(), LockService.class));
}//EOF Oncreate
}//EOF Activity
LockService.java
public class LockService extends Service {
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
final IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_USER_PRESENT);
final BroadcastReceiver mReceiver = new ScreenReceiver();
registerReceiver(mReceiver, filter);
return super.onStartCommand(intent, flags, startId);
}
public class LocalBinder extends Binder
{
LockService getService() {
return LockService.this;
}
}//EOF SERVICE
ScreenReceiver.java
public class ScreenReceiver extends BroadcastReceiver {
public static boolean wasScreenOn = true;
public void onReceive(final Context context, final Intent intent) {
Log.e("LOB","onReceive");
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF))
{
// do whatever you need to do here
wasScreenOn = false;
//Log.e("LOB","wasScreenOn"+wasScreenOn);
Log.e("Screen ","shutdown now");
}
else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON))
{
// and do whatever you need to do here
wasScreenOn = true;
Log.e("Screen ","awaked now");
Intent i = new Intent(context, MainActivity.class); //MyActivity can be anything which you want to start on bootup...
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
else if(intent.getAction().equals(Intent.ACTION_USER_PRESENT))
{
Log.e("LOB","userpresent");
// Log.e("LOB","wasScreenOn"+wasScreenOn);
}
}
}//EOF SCREENRECEIVER.JAVA
Now this is xml file, Please copy paste and just change the package name you are using
<?xml version="1.0" encoding="utf-8"?>
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="21" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.userpresent.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name="com.example.userpresent.LockService" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</service>
</application>