I'm trying to use google's geofences and I follow the google docs
The problem is that when I call addGeofences() it should start the IntentService but it just stopped.
The addGeofences() result always shows success and my Log:
and then nothing happens,
my IntentService's onHandleIntent()'s Log shows nothing; I think it's not even activated.
I used Nexus5 API25 emulator and Target Android7.1.1(Google APIs)for testing.
I searched much but still can't figure out why; maybe I missed something.
here is my code:
private void startGeofenceMonitor()
{
Log.i("info", "Start geofence monitoring");
try
{
int permission = ActivityCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.ACCESS_FINE_LOCATION);
if (permission != PackageManager.PERMISSION_GRANTED)
{
ActivityCompat.requestPermissions( MainActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION} , PERMISSIONS_REQUEST_CODE);
Log.i("info", "Permission not available! ");
}
else
{
mGeofencingClient = LocationServices.getGeofencingClient(this);
geofenceList.add(new Geofence.Builder().setRequestId("point0")
.setCircularRegion(55, 55, 15)
.setExpirationDuration(Geofence.NEVER_EXPIRE)
.setNotificationResponsiveness(1000)
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER | Geofence.GEOFENCE_TRANSITION_EXIT)
.build());
mGeofencingClient.addGeofences(getGeofencingRequest(), getGeofencePendingIntent())
.addOnSuccessListener(this, new OnSuccessListener<Void>()
{
#Override
public void onSuccess(Void aVoid)
{
Log.i("info", "geofence added!: ");
}
})
.addOnFailureListener(new OnFailureListener()
{
#Override
public void onFailure(#NonNull Exception e)
{
Log.i("info", "geofence failed! " + e.toString());
}
});
}
}
catch (Exception e)
{
Log.i("er", e.getMessage());
}
}
private GeofencingRequest getGeofencingRequest()
{
return new GeofencingRequest.Builder()
.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER | GeofencingRequest.INITIAL_TRIGGER_DWELL)
.addGeofences(geofenceList)
.build();
}
private PendingIntent getGeofencePendingIntent()
{
if (mGeofencePendingIntent != null)
{
return mGeofencePendingIntent;
}
Intent intent = new Intent(this, GeofenceTransitionsIntentService.class);
mGeofencePendingIntent = PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
return mGeofencePendingIntent;
}
and my IntentSrvice
public GeofenceTransitionsIntentService()
{
super("GeofenceTransitionsIntentService");
Log.i("info", "IntentService is activated!");
}
#Override
protected void onHandleIntent(Intent intent)
{
String test = intent.getStringExtra("pls");
Log.i("info", "onHandleIntent is activated!");
GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);
Log.i("info", "geofencingEvent size: " + intent.toString());
if (geofencingEvent.hasError())
{
Log.e("er", "geofencingEvent has error!");
return;
}
else
{
}
int geofenceTransition = geofencingEvent.getGeofenceTransition();
Log.e("er", "geofenceTransition" + geofenceTransition);
if (geofenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER)
{
List<Geofence> triggeringGeofences = geofencingEvent.getTriggeringGeofences();
Geofence geofence = triggeringGeofences.get(0);
String requestID = geofence.getRequestId();
Log.i("geo", "Entering geofence : " + requestID);
}
else if (geofenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT)
{
Log.i("geo", "Exiting geofence : ");
}
else
{
Log.i("geo", "geo not in range ");
}
}
manifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.hs.geofencestest">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".GeofenceTransitionsIntentService" android:exported="true"/>
</application>
Related
I'm creating an app. which is always wants to trigger when the phone call states changes (Phone state listener), but my Broadcast receiver killed by Android after a few minutes So I created a Foreground service to keep the app running in the background, but the thing is After I installed the app I start the foreground service in the MainActivity through button click, then if the broadcast receiver triggers my foreground service stops. I think Service and Broadcast receiver using the same thread I guess. How can I Archive that I below coding
Manifest
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity"></activity>
<activity android:name=".MainActivity2">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity> <!-- This part is inside the application -->
<service android:name=".HammerService" android:enabled="true" />
<receiver
android:name=".CallReceiver"
android:enabled="true">
<intent-filter android:priority="999">
<action android:name="android.intent.action.PHONE_STATE" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
</receiver>
</application>
MainActivity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn=findViewById(R.id.button);
checkAndRequestPermissions();
final Intent serviceIntent = new Intent(this, HammerService.class);
serviceIntent.putExtra("inputExtra", "Call Hammer ");
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
ContextCompat.startForegroundService(MainActivity.this, serviceIntent);
}
}
});
}
private boolean checkAndRequestPermissions() {
int readPhoneState = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE);
int read_call_log = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CALL_LOG);
List listPermissionsNeeded = new ArrayList<>();
if (readPhoneState != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.READ_PHONE_STATE);
}
if (read_call_log != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.READ_CALL_LOG);
}
if (read_call_log != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.PROCESS_OUTGOING_CALLS);
}
if (read_call_log != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.INTERNET);
}
if (!listPermissionsNeeded.isEmpty()) {
ActivityCompat.requestPermissions(this,
(String[]) listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]),
REQUEST_ID_MULTIPLE_PERMISSIONS);
return false;
}
return true;
}
> App
public class App extends Application {
public static final String CHANNEL_ID = "exampleServiceChannel";
#Override
public void onCreate() {
super.onCreate();
createNotificationChannel();
}
private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel serviceChannel = new NotificationChannel(
CHANNEL_ID,
"Example Service Channel",
NotificationManager.IMPORTANCE_DEFAULT
);
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(serviceChannel);
}
}
}
HammerService
public class HammerService extends Service {
#Override
public void onCreate() {
super.onCreate();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
startMyOwnForeground();
else
startForeground(1, new Notification());
}
#RequiresApi(api = Build.VERSION_CODES.O)
private void startMyOwnForeground() {
// String NOTIFICATION_CHANNEL_ID = "com.example.simpleapp";
String channelName = "Call Hummer Background Service";
NotificationChannel chan = new NotificationChannel(CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_NONE);
chan.setLightColor(Color.BLUE);
chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
assert manager != null;
manager.createNotificationChannel(chan);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, CHANNEL_ID);
Notification notification = notificationBuilder.setOngoing(true)
.setSmallIcon(R.drawable.ic_android)
.setContentTitle("Call Hammer Service")
.setPriority(NotificationManager.IMPORTANCE_MIN)
.setCategory(Notification.CATEGORY_SERVICE)
.build();
startForeground(2, notification);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
String input = intent.getStringExtra("inputExtra");
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,
0, notificationIntent, 0);
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Call Hammer Service")
.setContentText(input)
.setSmallIcon(R.drawable.ic_android)
.setContentIntent(pendingIntent)
.build();
startForeground(1, notification);
//do heavy work on a background thread
//stopSelf();
return START_NOT_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
CallReciverclass
public class CallReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
try {
runfirstTime(context,intent);
Toast.makeText(context, "1st", Toast.LENGTH_SHORT).show();
} catch (Exception ex) {
try {
}
catch (Exception e)
{
}
}
}
}
I am trying to make my map app redirect to the settings for location permissions and once permissions are granted redirect again to the app. for some reason my onActivityResult is not even called after starting the activity intent. and basically what happens is when I click on the snackbar action button that appears, it starts the settingsIntent and redirects me to the settings nicely but the activity isn't going for result state and the onActivityResult is never called
any suggestions?
here is the code:
class MapsActivity : AppCompatActivity(), OnMapReadyCallback {
private lateinit var mMap: GoogleMap
private fun checkPermissions(): Boolean {
//returns true if granted permission for location
var checker = ActivityCompat.checkSelfPermission(
applicationContext,
android.Manifest.permission.ACCESS_COARSE_LOCATION
) == PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
applicationContext,
android.Manifest.permission.ACCESS_FINE_LOCATION
) == PackageManager.PERMISSION_GRANTED
if (checker) {
Log.d(TAG, "granted Permissions")
} else {
Log.d(TAG, "no Permissions granted")
}
return checker
}
#RequiresApi(Build.VERSION_CODES.M)
private fun requestPermissions() {
requestPermissions(
arrayOf(
android.Manifest.permission.ACCESS_COARSE_LOCATION,
android.Manifest.permission.ACCESS_FINE_LOCATION
), PERMISSION_ID
)
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (!checkPermissions()) {
Snackbar.make(
map.view!!,
"Please Enable Location Permission",
Snackbar.LENGTH_INDEFINITE
).setAction("Enable Location",
View.OnClickListener {
var settingsIntent = Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)
startActivityForResult(settingsIntent, 1)
})
.show()
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
Log.d(TAG, "Redirected to settings for Location Permissions ")
if (resultCode == Activity.RESULT_OK) {
if (checkPermissions()) {
Log.d(TAG, "Permissions granted from settings")
startActivity(Intent(this, MapsActivity::class.java))
}
}
super.onActivityResult(requestCode, resultCode, data)
}
override fun onCreate(savedInstanceState: Bundle?) {
Log.d(TAG, "onCreate called")
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_maps)
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
val mapFragment = supportFragmentManager
.findFragmentById(R.id.map) as SupportMapFragment
mapFragment.getMapAsync(this)
}
#RequiresApi(Build.VERSION_CODES.M)
override fun onMapReady(googleMap: GoogleMap) {
Log.d(TAG, "omMapReady:starts")
mMap = googleMap
requestPermissions()
}
}
manifest :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.burgertracker">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
<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">
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="#string/google_maps_key" />
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<activity
android:name=".MapsActivity"
android:label="#string/title_activity_maps">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
This is working for me,
MainActivity
import android.content.Intent
import android.os.Bundle
import android.provider.Settings
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
findViewById<TextView>(R.id.tv_click).setOnClickListener {
val settingsIntent = Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)
startActivityForResult(settingsIntent, 1)
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
Toast.makeText(this, "Hakuna Mattat", Toast.LENGTH_SHORT).show()
}
}
activity_main_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="#+id/tv_click"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.demointentapplication">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
I navigate to Settings page when I click the TextView on MainActivity and when I press back from Settings page I see the Toast message Hakuna Mattat everytime.
there are some differences between our codes, your code is just on a regular activity and mine is on a mapActivity which has a map Fragment displayed.. i run the startActivityForResult from my onRequestPermissiosnResult function since i need to to run only if the permissions are not granted.. so i guess any of those must be the reason..
also i checked and the onActivityResult is called only when i press back once the location settings is displayed.. but the problem is that i need to click on the app in that location setting page and then allow location for it and if i do so and then press home button 2 times to go back the the app it does not go back and onActivityResult is not called..
so either i need to know if theres an option to start an intent that will start an activity that goes directly to my specific app location settings and then i guess it will work or either if i will know how to control that settings activity because once it moves to the settings the mapAcitivty is stopped..
int PERMISSION_ID = 44;
FusedLocationProviderClient mFusedLocationClient;
#RequiresApi(api = Build.VERSION_CODES.M)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.activity_home);
mFusedLocationClient =
LocationServices.getFusedLocationProviderClient(this);
getLastLocation();
}
private boolean checkPermissions() {
if (ActivityCompat.checkSelfPermission(HomeActivity.this,
Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(HomeActivity.this,
Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
return true;
}
return false;
}
private void requestPermissions() {
ActivityCompat.requestPermissions(
HomeActivity.this,
new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION},
PERMISSION_ID
);
}
private boolean isLocationEnabled() {
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || locationManager.isProviderEnabled(
LocationManager.NETWORK_PROVIDER
);
}
#RequiresApi(api = Build.VERSION_CODES.M)
#SuppressLint("MissingPermission")
private void getLastLocation() {
if (checkPermissions()) {
if (isLocationEnabled()) {
mFusedLocationClient.getLastLocation().addOnCompleteListener(
new OnCompleteListener<Location>() {
#Override
public void onComplete(#NonNull Task<Location> task) {
Location location = task.getResult();
if (location == null) {
requestNewLocationData();
} else {
Geocoder geocoder = new Geocoder(HomeActivity.this, Locale.getDefault());
List<Address> addresses = null;
try {
addresses = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1);
} catch (IOException e) {
e.printStackTrace();
}
assert addresses != null;
if (addresses != null) {
String cityName = addresses.get(0).getAddressLine(0);
String stateName = addresses.get(0).getAddressLine(1);
String countryName = addresses.get(0).getAddressLine(2);
String[] arrOfStr = cityName.split(",");
locationTV.setText("You're in " + arrOfStr[arrOfStr.length - 2] + ", " + arrOfStr[arrOfStr.length - 1]);
}
}
}
}
);
} else {
Toast.makeText(this, "Turn on location", Toast.LENGTH_LONG).show();
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
}
} else {
requestPermissions();
}
}
#RequiresApi(api = Build.VERSION_CODES.M)
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == PERMISSION_ID) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
getLastLocation();
}
}
}
#RequiresApi(api = Build.VERSION_CODES.M)
#Override
public void onResume() {
super.onResume();
if (checkPermissions()) {
getLastLocation();
}
}
#SuppressLint("MissingPermission")
private void requestNewLocationData() {
LocationRequest mLocationRequest = new LocationRequest();
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setInterval(0);
mLocationRequest.setFastestInterval(0);
mLocationRequest.setNumUpdates(1);
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
mFusedLocationClient.requestLocationUpdates(
mLocationRequest, mLocationCallback,
Looper.myLooper()
);
}
private LocationCallback mLocationCallback = new LocationCallback() {
#Override
public void onLocationResult(LocationResult locationResult) {
Location mLastLocation = locationResult.getLastLocation();
Geocoder geocoder = new Geocoder(HomeActivity.this, Locale.getDefault());
List<Address> addresses = null;
try {
addresses = geocoder.getFromLocation(mLastLocation.getLatitude(), mLastLocation.getLongitude(), 1);
} catch (IOException e) {
e.printStackTrace();
}
assert addresses != null;
if (addresses != null) {
String cityName = addresses.get(0).getAddressLine(0);
String stateName = addresses.get(0).getAddressLine(1);
String countryName = addresses.get(0).getAddressLine(2);
String[] arrOfStr = cityName.split(",");
locationTV.setText("You're in " + arrOfStr[arrOfStr.length - 2] + ", " +
arrOfStr[arrOfStr.length - 1]);
}
}
};
I'm trying to create an Internet connection listener. But not working. I'm not getting any mistakes.I think the NetworkStateChangeReceiver does not work at all. Because Log.e does not appear in logcat. I'm new to Android and it's complicated for me.
Android manifest
<receiver
android:name=".NetworkStateChangeReceiver">
<intent-filter >
<action android:name="com.gdm.retailalfageek.NetworkAvailable" />
</intent-filter>
</receiver>
NetworkStateChangeReceiver.java
public class NetworkStateChangeReceiver extends BroadcastReceiver {
public static final String NETWORK_AVAILABLE_ACTION = "com.gdm.retailalfageek.NetworkAvailable";
public static final String IS_NETWORK_AVAILABLE = "isNetworkAvailable";
#Override
public void onReceive(Context context, Intent intent) {
Intent networkStateIntent = new Intent(NETWORK_AVAILABLE_ACTION);
networkStateIntent.putExtra(IS_NETWORK_AVAILABLE, getConnectionType(context));
LocalBroadcastManager.getInstance(context).sendBroadcast(networkStateIntent);
Log.e("Network Available ", "On receive called");
}
#IntRange(from = 0, to = 2)
public static int getConnectionType(Context context) {
int result = 0; // Returns connection type. 0: none; 1: mobile data; 2: wifi
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (cm != null) {
NetworkCapabilities capabilities = cm.getNetworkCapabilities(cm.getActiveNetwork());
Log.e("Network Available ", "On receive called");
if (capabilities != null) {
if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
Log.e("Network Available ", "On receive called");
result = 2;
} else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
Log.e("Network Available ", "On receive called");
result = 1;
}
}
}
} else {
if (cm != null) {
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
if (activeNetwork != null) {
Log.e("Network Available ", "On receive called");
// connected to the internet
if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI) {
Log.e("Network Available ", "On receive called");
result = 2;
} else if (activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE) {
Log.e("Network Available ", "On receive called");
result = 1;
}
}
}
}
return result;
}}
Application class
#Override
public void onCreate() {
super.onCreate();
IntentFilter filter = new IntentFilter();
filter.addAction("isNetworkAvailable");
registerReceiver(new NetworkStateChangeReceiver(), filter);
}
Hope the code given below help you.
Register a BroadcastReceiver in Manifest.file
<receiver android:name=".MyBroadcastReceiver" >
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
Set internet permissions in Manifest
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET"/>
Implement receiving class.
public class MyBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// This will execute upon receiving event
}
}
I did login with facebook in the Activity
private CallbackManager callbackManager;
private LoginButton loginFBButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(LAYOUT);
callbackManager = CallbackManager.Factory.create();
loginFBButton = (LoginButton) findViewById(R.id.loginFBButton);
loginFBButton.setReadPermissions(Arrays.asList("email", "public_profile"));
loginFBButton.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
final String accessToken = loginResult.getAccessToken().getToken();
LogTag.v("onSuccess - getToken - " + accessToken);
GraphRequest request = GraphRequest.newMeRequest(
loginResult.getAccessToken(),
new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject object, GraphResponse response) {
LogTag.v("onSuccess - " + response.toString());
// Application code
try {
String email = object.getString("email");
LogTag.v("email - " + email);
String name = object.getString("name");
LogTag.v("name - " + name);
saveUserData(name, email, accessToken);
} catch (JSONException e) {
e.printStackTrace();
}
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "id,name,email,gender,birthday");
request.setParameters(parameters);
request.executeAsync();
}
#Override
public void onCancel() {
LogTag.v("onCancel");
}
#Override
public void onError(FacebookException error) {
LogTag.v("onError - " + error.getMessage());
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
callbackManager.onActivityResult(requestCode, resultCode, data);
}
in gradle
dependencies { compile 'com.facebook.android:facebook-android-sdk:4.11.0' }
in AndroidManifest
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example">
<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" />
<application
android:name=".application.MyApp"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<meta-data
android:name="com.facebook.sdk.ApplicationId"
android:value="#string/facebook_app_id" />
<activity
android:name=".activity.ActivitySignIn"
android:label="#string/app_name"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.facebook.FacebookActivity"
android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation"
android:label="#string/app_name"
android:theme="#android:style/Theme.Translucent.NoTitleBar" />
</application>
in MyApp
public class MyApp extends Application {
#Override
public void onCreate() {
super.onCreate();
FacebookSdk.sdkInitialize(getApplicationContext());
} }
but it does not always work on 4.4.2 - OK, in the phone (5.1) on one normal and the other hangs after login with a progress bar under which there is a notice of confirmation of access to personal data, and then triggers onCancel
On your phone, which it might be a bug in the log shows a link to the message:
{ "error": {
"message": "An access token is required to request this resource.",
"type": "OAuthException",
"code": 104,
"fbtrace_id": "AV/53FbmMya" } }
What is the problem? How to solve it?
Try this code i use in fragment.
FacebookSdk.sdkInitialize(getActivity());
callbackManager = CallbackManager.Factory.create();
LoginManager.getInstance().registerCallback(callbackManager,
new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
// App code
accessToken = loginResult.getAccessToken()
.getToken();
Log.i("accessToken", accessToken);
}
#Override
public void onCancel() {
// App code
Toast.makeText(getActivity(), "on Cancel", Toast.LENGTH_SHORT).show();
}
#Override
public void onError(FacebookException exception) {
// App code
Toast.makeText(getActivity(), "on Error", Toast.LENGTH_SHORT).show();
IRoidAppHelper.Log("FacebokkError", exception.toString());
}
});`
Im trying to add notifications to my android app. So I decided to implement GCM.
I have used the sample code from the official documentation
https://developer.android.com/google/gcm/client.html
and the sample application
https://code.google.com/p/gcm/source/browse/samples/gcm-demo-client/src/com/google/android/gcm/demo/app/
Here is my implementation
public class RegisterActivity extends Activity implements SurfaceHolder.Callback{
public static final String PROPERTY_REG_ID = "registration_id";
private static final String PROPERTY_APP_VERSION = "appVersion";
private static final int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;
String SENDER_ID = "210822831159";
GoogleCloudMessaging gcm;
AtomicInteger msgId = new AtomicInteger();
Context context;
String regid;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
context = getApplicationContext();
if (checkPlayServices())
{
gcm = GoogleCloudMessaging.getInstance(this);
regid = getRegistrationId(context);
if (regid.isEmpty())
{
registerInBackground();
}
else
{
//"No valid Google Play Services APK found."
}
}
//...
}
#Override
protected void onResume() {
super.onResume();
// Check device for Play Services APK.
checkPlayServices();
}
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 {
finish();
}
return false;
}
return true;
}
private void storeRegistrationId(Context context, String regId) {
final SharedPreferences prefs = getGcmPreferences(context);
int appVersion = getAppVersion(context);
SharedPreferences.Editor editor = prefs.edit();
editor.putString(PROPERTY_REG_ID, regId);
editor.putInt(PROPERTY_APP_VERSION, appVersion);
editor.commit();
}
private String getRegistrationId(Context context) {
final SharedPreferences prefs = getGcmPreferences(context);
String registrationId = prefs.getString(PROPERTY_REG_ID, "");
if (registrationId.isEmpty()) {
return "";
}
int registeredVersion = prefs.getInt(PROPERTY_APP_VERSION, Integer.MIN_VALUE);
int currentVersion = getAppVersion(context);
if (registeredVersion != currentVersion) {
return "";
}
return registrationId;
}
private void registerInBackground() {
new AsyncTask<Void, Void, String>() {
#Override
protected String doInBackground(Void... params) {
String msg = "";
try {
if (gcm == null) {
gcm = GoogleCloudMessaging.getInstance(context);
}
regid = gcm.register(SENDER_ID);
msg = "Device registered, registration ID=" + regid;
sendRegistrationIdToBackend();
storeRegistrationId(context, regid);
} catch (IOException ex) {
msg = "Error :" + ex.getMessage();
}
return msg;
}
#Override
protected void onPostExecute(String msg) {
//...
}
}.execute(null, null, null);
}
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);
}
}
private SharedPreferences getGcmPreferences(Context context) {
return getSharedPreferences(RegisterActivity.class.getSimpleName(),
Context.MODE_PRIVATE);
}
private void sendRegistrationIdToBackend() {
// TODO
}
//...
}
The Broadcaster:
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);
}
}
Intent Service:
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++) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
}
// Post notification of received message.
sendNotification("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, HomeActivity.class), 0);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setContentTitle("GCM Notification")
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(msg))
.setContentText(msg);
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
}
}
Android Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.HBM.sample" >
<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="android.permission.VIBRATE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission android:name="com.HBM.sample.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.HBM.sample.permission.C2D_MESSAGE" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<receiver
android:name=".GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.HBM.sample" />
</intent-filter>
</receiver>
<service
android:name=".GcmIntentService"
android:enabled="true" />
<activity
android:name=".RegisterActivity"
android:windowSoftInputMode="stateHidden|adjustResize" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".HomeActivity"
android:windowSoftInputMode="stateHidden|adjustResize" >
android:label="#string/title_activity_home" >
</activity>
<meta-data android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
</application>
</manifest>
The app compiles fine and when I set a breakpoint in registerInBackground after:
regid = gcm.register(SENDER_ID);
the client registers fine and I get the registration id that looks something like this:
APA91bEdxx0UyqtX6qoVuhYNSeJkuAITIpdkbCkBCCsOyX5-lpbtNAJBvvGqIGKqxGhW24-y-tWbj2EDKJAiyvzVhP7jhMevZBr-o-Y6Eli0uG24oWXjFOWa1Sj9vjNXaO5wbWs7WodC4Oq4QOFaPQscF_v44Z_kyg
After that I created a GCM Server application and send a notification to the registrationId
Here is the json response:
{"multicast_id":5827029040432755439,"success":1,"failure":0,"canonical_ids":0,"results":[{"message_id":"0:1407451852374547%913f6fe1f9fd7ecd"}]}
It looks like the app registers fine and the notifications are pushed successfully. But onReceive never fires and I dont get any notifications o_O
I have tried the app on two different phones and different networks. But Im not sure what Im doing wrong. I hope someone can help me. I would really appreciate it.