I'm very new to android studio and in my first app I want to build an sos app, my sos app specifically sends a message via sms with the current location. When I first built it, it only works on android 5.0 and down, it will not work in 6.0 and up and now I've tried to look at the logcat and the logcat says it needs a permission to send sms so I gave it a permission using the code below this paragraph and now it runs in android 6.0 but it's not sending messages... {if(checkselfpermission(Manifest.permission.SEND_SMS)==PackageManager.PERMISSION GRANTED);}
can you help me here is my manifest my file
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.ACCESS_COURSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application
android:allowBackup="true"
android:icon="#mipmap/sos"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:theme="#style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!--
ATTENTION: This was auto-generated to add Google Play services to your project for
App Indexing. See https://g.co/AppIndexing/AndroidStudio for more information.
-->
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<activity
android:name=".DisplayContactActivity"
android:label="#string/title_activity_display_contact"
android:parentActivityName=".MainActivity"
android:theme="#style/AppTheme.NoActionBar" />
<activity
android:name=".EditContactActivity"
android:label="#string/title_activity_edit_contact"
android:parentActivityName=".DisplayContactActivity"
android:theme="#style/AppTheme.NoActionBar" />
<activity
android:name=".DisplayMessageActivity"
android:label="#string/title_activity_display_message"
android:parentActivityName=".MainActivity"
android:theme="#style/AppTheme.NoActionBar" />
<activity
android:name=".LogInActivity"
android:label="#string/title_activity_log_in"
android:parentActivityName=".MainActivity"
android:theme="#style/AppTheme.NoActionBar"></activity>
</application>
and here is my main activity.
public class MainActivity extends AppCompatActivity {
private static final int PERMISSION_SEND_SMS = 1;
ContactDbAdapter contactDbAdapter;
private GoogleApiClient client;
EditText messageText;
UserDbAdapter userDbAdapter;
Cursor cursor;
TextView locationText;
#Override
public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
return super.checkUriPermission(uri, pid, uid, modeFlags);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
userDbAdapter = new UserDbAdapter(this);
messageText = (EditText) findViewById(R.id.messageText);
locationText = (TextView) findViewById(R.id.locationTextView);
try {
userDbAdapter.open();
} catch (SQLException error) {
Log.e("mytag", "Error open userDbAdapter\n");
}
contactDbAdapter = new ContactDbAdapter(this);
try {
contactDbAdapter.open();
} catch (SQLException error) {
Log.e("mytag", "Error open contactDbAdapter\n");
}
cursor = contactDbAdapter.getContacts();
final Button sos = (Button) findViewById(R.id.redbutton);
final Button finish = (Button) findViewById(R.id.greenbutton);
final CountDownTimer timer = new CountDownTimer(3999, 100) {
public void onTick(long millisUntilFinished) {
assert sos != null;
sos.setText("" + ((int) (millisUntilFinished) / 1000));
}
#TargetApi(Build.VERSION_CODES.M)
public void onFinish() {
sos.setVisibility(View.GONE);
finish.setVisibility(View.VISIBLE);
finish.setText("finish");
SmsManager smsManager = SmsManager.getDefault();
cursor = contactDbAdapter.getContacts();
String msg = messageText.getText().toString() + "#" + locationText.getText().toString();
Log.e("mytag", msg);
if(cursor.moveToFirst()){
do{
if (checkSelfPermission(Manifest.permission.SEND_SMS)==PackageManager.PERMISSION_GRANTED);
String number=cursor.getString(cursor.getColumnIndex(contactDbAdapter.PHONE_NUM));
smsManager.sendTextMessage(number, null, msg, null, null);
}while(cursor.moveToNext());
}
}
};
sos.setTag(1);
sos.setOnClickListener(
new Button.OnClickListener() {
public void onClick(View v) {
final int status = (Integer) v.getTag();
if (status != 1) {
sos.setText("sos");
sos.setTag(1);
timer.cancel();
} else {
sos.setTag(0);
timer.start();
}
}
}
);
finish.setOnClickListener(
new Button.OnClickListener() {
public void onClick(View v) {
sos.setVisibility(View.VISIBLE);
finish.setVisibility(View.GONE);
sos.callOnClick();
}
}
);
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information
client = new GoogleApiClient.Builder(this).addApi(AppIndex.API).build();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#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
switch (id) {
case R.id.contact:
Intent contactIntent = new Intent(getApplicationContext(), LogInActivity.class);
startActivity(contactIntent);
return true;
case R.id.message:
Intent messageIntent = new Intent(getApplicationContext(), DisplayMessageActivity.class);
startActivity(messageIntent);
default:
break;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onStart() {
super.onStart();
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
client.connect();
Action viewAction = Action.newAction(
Action.TYPE_VIEW, // TODO: choose an action type.
"Main Page", // TODO: Define a title for the content shown.
// TODO: If you have web page content that matches this app activity's content,
// make sure this auto-generated web page URL is correct.
// Otherwise, set the URL to null.
Uri.parse("http://host/path"),
// TODO: Make sure this auto-generated app deep link URI is correct.
Uri.parse("android-app://com.cse4471.osu.sos_osu/http/host/path")
);
AppIndex.AppIndexApi.start(client, viewAction);
}
#Override
public void onResume() {
super.onResume();
// refresh user message
cursor = userDbAdapter.getUsers();
if (cursor.moveToFirst()) {
messageText.setText(cursor.getString(cursor.getColumnIndex(userDbAdapter.MESSAGE)));
}
// Acquire a reference to the system Location Manager
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{
Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.INTERNET}, 10);
return;
}
LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
// Called when a new location is found by the network location provider.
locationText.setText("Latitude:" + location.getLatitude() + ", Longitude:" + location.getLongitude());
}
public void onStatusChanged(String provider, int status, Bundle extras) {
}
public void onProviderEnabled(String provider) {
}
public void onProviderDisabled(String provider) {
}
};
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 3000, 0, locationListener);
Location loc = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if(loc != null) {
// messageText.setText("Latitude:" + loc.getLatitude() + ", Longitude:" + loc.getLongitude());
locationText.setText("Latitude:" + loc.getLatitude() + ", Longitude:" + loc.getLongitude());
}
}
#Override
public void onStop() {
super.onStop();
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
Action viewAction = Action.newAction(
Action.TYPE_VIEW, // TODO: choose an action type.
"Main Page", // TODO: Define a title for the content shown.
// TODO: If you have web page content that matches this app activity's content,
// make sure this auto-generated web page URL is correct.
// Otherwise, set the URL to null.
Uri.parse("http://host/path"),
// TODO: Make sure this auto-generated app deep link URI is correct.
Uri.parse("android-app://com.cse4471.osu.sos_osu/http/host/path")
);
AppIndex.AppIndexApi.end(client, viewAction);
client.disconnect();
}
#Override
public void onDestroy() {
super.onDestroy();
if (cursor != null) {
cursor.close();
}
}
this is also the logcat that appeared before I gave the permission to run it on android 6.0
Process: com.cse4471.osu.sos_osu, PID: 23011
java.lang.SecurityException: Sending SMS message: uid 10179 does not have android.permission.SEND_SMS.
at android.os.Parcel.readException(Parcel.java:1620)
at android.os.Parcel.readException(Parcel.java:1573)
at com.android.internal.telephony.ISms$Stub$Proxy.sendTextForSubscriber(ISms.java:842)
at android.telephony.SmsManager.sendTextMessageInternal(SmsManager.java:317)
at android.telephony.SmsManager.sendTextMessage(SmsManager.java:300)
at com.cse4471.osu.sos_osu.MainActivity$1.onFinish(MainActivity.java:119)
at android.os.CountDownTimer$1.handleMessage(CountDownTimer.java:127)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5628)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:853)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:737)
I hope you can help me with this.
You can try this :-
Add it in Manifest -
<uses-permission android:name="android.permission.SEND_SMS" />
And use this runtime permission in your activity
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.SEND_SMS},1);
Related
I want the first LoginActivity.java page to open in my project, but AnasayfaActivity.java opens. I couldn't solve the problem. I use Android Studio. I am learning Android, and I would be glad if you help. I shared LoginActivity and AndroidManifest pages. When the application is opened for the first time, the Home Activity opens, when I go back, it goes to the LoginActivity.java page.
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.geziproject">
>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<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/Theme.Geziproject">
<activity android:name=".AnasayfaActivity"/>
<activity android:name=".MainActivity2" />
<activity android:name=".LoginActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".MainActivity"
android:label="#string/title_activity_main"
android:theme="#style/Theme.Geziproject.NoActionBar">
</activity>
<activity android:name=".bos" />
<activity android:name=".kayitol" />
<activity android:name=".kullanicigiris" />
</application>
</manifest>
LoginActivity.java:
public class LoginActivity extends AppCompatActivity {
private Button signInButton;
private GoogleSignInClient mGoogleSignInClient;
private FirebaseAuth mAuth;
private Button signout;
Button btngiris;
Button btnkayit;
private EditText txtad;
private EditText txtemail;
private EditText txtsifre;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
Button btngiris = findViewById(R.id.btngiris);
Button btnkayit = findViewById(R.id.btnkayit);
txtemail = findViewById(R.id.txtemail);
txtsifre = findViewById(R.id.txtsifre);
signInButton = findViewById(R.id.signin);
mAuth = FirebaseAuth.getInstance();
// signout = findViewById(R.id.sign_out);
btngiris.setOnClickListener(v -> {
String email=txtemail.getText().toString();
String pwd= txtsifre.getText().toString();
if(email.isEmpty()){
txtemail.setError("Lütfen email giriniz");
txtemail.requestFocus();
}
else if(pwd.isEmpty()){
txtsifre.setError("Lütfen şifre giriniz");
txtsifre.requestFocus();
}
else if(email.isEmpty() && pwd.isEmpty())
{
Toast.makeText(LoginActivity.this,"Bu alanlar boş bırakılamaz",Toast.LENGTH_LONG).show();
}
else if(!(email.isEmpty() && pwd.isEmpty())){
mAuth.signInWithEmailAndPassword(email,pwd).addOnCompleteListener(LoginActivity.this, task -> {
if(!task.isSuccessful()){
Toast.makeText(LoginActivity.this,"Giriş başarısız ,tekrar deneyiniz",Toast.LENGTH_LONG).show();
}
else{
Toast.makeText(LoginActivity.this,"Giriş başarılı",Toast.LENGTH_LONG).show();
txtemail.setText("");
txtsifre.setText("");
startActivity(new Intent(LoginActivity.this,AnasayfaActivity.class));
}
});
}
else{
Toast.makeText(LoginActivity.this,"Hata oluştu",Toast.LENGTH_LONG).show();
}
});
btnkayit.setOnClickListener(v -> {
Intent i= new Intent(LoginActivity.this,kayitol.class);
startActivity(i);
});
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken("1088981466528-8pkjha8350r2uniqg2425nv5itvgpvr7.apps.googleusercontent.com")
.requestEmail()
.build();
mGoogleSignInClient = GoogleSignIn.getClient(this, gso);
signInButton.setOnClickListener(v -> signIn());
FirebaseUser user = mAuth.getCurrentUser();
if (user != null) {
startActivity(new Intent(LoginActivity.this, AnasayfaActivity.class).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
}
}
private void signIn() {
Intent signInIntent = mGoogleSignInClient.getSignInIntent();
startActivityForResult(signInIntent, 100);
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 100) {
Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
//handleSignInResult(task);
if (task.isSuccessful()) {
String s = "Google sign in Successful";
displayToast(s);
try {
GoogleSignInAccount account = task.getResult(ApiException.class);
Toast.makeText(getApplicationContext(), "giriş başarılı", Toast.LENGTH_LONG).show();
if (account != null) {
AuthCredential credential = GoogleAuthProvider.getCredential(account.getIdToken(), null);
mAuth.signInWithCredential(credential).addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
Intent intent = new Intent(getApplicationContext(), AnasayfaActivity.class);
startActivity(intent);
}
}
});
}
} catch (ApiException e) {
e.printStackTrace();
}
}
}
}
private void displayToast(String s) {
Toast.makeText(getApplicationContext(), s, Toast.LENGTH_LONG).show();
}
}
As you set the launch activity in mainfest to LoginActivity, the app starts normally with the LoginActivity, but before the LoginActivity is resumend (i.e. shown on the screen) you added a condition in onCreate() method to launch the AnasayfaActivity as below:
FirebaseUser user = mAuth.getCurrentUser();
if (user != null) {
startActivity(new Intent(LoginActivity.this, AnasayfaActivity.class)
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
}
If the user is not null (i.e. already logged-in), then the app goes directly to AnasayfaActivity activity without showing the LoginActivity to the user.
And the reason when you go back; the app go to the LoginActivity, because the LoginActivity is still in the back stack. If you want to remove the LoginActivity from the back stack then add Intent.FLAG_ACTIVITY_CLEAR_TOP to the intent:
startActivity(new Intent(LoginActivity.this, AnasayfaActivity.class)
.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));
Actually I'm building an application which requires user's location. But I'm getting SERVICE_VERSION_UPDATE_REQUIRED error. Following are my MainActivity.java and AndroidManifest.xml files:
MainActivity.java
TextView lat, lon;
private static final String TAG = MainActivity.class.getSimpleName();
private FusedLocationProviderApi locationProvider = LocationServices.FusedLocationApi;
private GoogleApiClient googleApiClient;
private LocationRequest locationRequest;
private double latitude, longitude;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lat = (TextView) findViewById(R.id.lat);
lon = (TextView) findViewById(R.id.lon);
if (googleApiClient == null) {
googleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
}
locationRequest = new LocationRequest();
locationRequest.setInterval(10000);
locationRequest.setFastestInterval(1000);
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
#Override
public void onConnected(#Nullable Bundle bundle) {
requestLocationUpdates();
}
private void requestLocationUpdates() {
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this);
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
Log.d(TAG, connectionResult.toString());
}
#Override
public void onLocationChanged(Location location) {
latitude = location.getLatitude();
longitude = location.getLongitude();
lat.setText("Latitude: " + String.valueOf(latitude));
lon.setText("Longitude: " + String.valueOf(longitude));
}
#Override
protected void onStart() {
super.onStart();
googleApiClient.connect();
}
#Override
protected void onResume() {
super.onResume();
if (googleApiClient.isConnected()) {
requestLocationUpdates();
}
}
#Override
protected void onPause() {
super.onPause();
LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient, this);
}
#Override
protected void onStop() {
super.onStop();
googleApiClient.disconnect();
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.harshil.location">
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Here is what logcat says:
D/MainActivity: ConnectionResult{statusCode=SERVICE_VERSION_UPDATE_REQUIRED, resolution=null, message=null}
So, How to get through this problem?
I solved my problem by changing following line [in build.gradle] from:
compile 'com.google.android.gms:play-services:10.0.1'
to:
compile 'com.google.android.gms:play-services:9.8.0'
So, the problem is I am using higher version of Google Play Service for development than that installed on my device or emulator.
I came to my solution as follow:
1. I checked to update Google Play Service on my device but it says it is up-to-date.
2. I checked in App Manager to see the version of it, and I came to know that it is actually at 9.8.77. So I changed play-service version from 10.0.1 to 9.8.0.
Now, I am out of this problem.
Thank you.
Download the the google play store in your mobile and check it .for me i was not installed google play store in my mobile now i installed google play store ,its working fine.
I am developing an App to check Wifi points.
I am getting error "java.lang.SecurityException: Need ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission to get scan results" at wifiManager.getScanResults() even though I already declared those permissions.
main activity
public class MainActivity extends AppCompatActivity {
WifiManager wifiManager;
String[] wifis;
WifiReceiver wifiReceiver;
ListView wifiListView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
wifiListView = (ListView) findViewById(R.id.wifi_list);
wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
wifiReceiver = new WifiReceiver();
wifiManager.startScan();
}
protected void onPause() {
unregisterReceiver(wifiReceiver);
super.onPause();
}
protected void onResume() {
registerReceiver(wifiReceiver, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
super.onResume();
}
private class WifiReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
List<ScanResult> wifiScanList = wifiManager.getScanResults();
wifis = new String[wifiScanList.size()];
for (int i = 0; i < wifiScanList.size(); i++) {
wifis[i] = wifiScanList.get(i).toString();
}
wifiListView.setAdapter(new ArrayAdapter<>(getApplicationContext(), android.R.layout.simple_list_item_1, wifis));
}
}
manifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.sample">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
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>
I am on SDK 6.0
I observed similar question, but solution does not apply since I already declared permission.
Anyone know what might be problem? Thank you.
In Android M, you need to ask for the permission which is defined as dangerous in PermissionModel to the user before start using each time, it as such:
private boolean mayRequestLocation() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
return true;
}
if (checkSelfPermission(ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
return true;
}
if (shouldShowRequestPermissionRationale(ACCESS_FINE_LOCATION)) {
Snackbar.make(mView, R.string.permission_rationale, Snackbar.LENGTH_INDEFINITE)
.setAction(android.R.string.ok, new View.OnClickListener() {
#Override
#TargetApi(Build.VERSION_CODES.M)
public void onClick(View v) {
requestPermissions(new String[]{ACCESS_FINE_LOCATION}, REQUEST_FINE_LOCATION);
}
});
} else {
requestPermissions(new String[]{ACCESS_FINE_LOCATION}, REQUEST_FINE_LOCATION);
}
return false;
}
Add this to your Activity:
private static final int REQUEST_FINE_LOCATION=0
and load it during runtime with:
loadPermissions(Manifest.permission.ACCESS_FINE_LOCATION,REQUEST_FINE_LOCATION);
To evaluate the results of your permission request, you can override onRequestPermissionsResult method:
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case REQUEST_FINE_LOCATION: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// The requested permission is granted.
}
else{
// The user disallowed the requested permission.
}
return;
}
}
MADAO is right: you should turn on GPS to get the WIFI access point list.
But I'm not sure about PEERS_MAC_ADDRESS. If you look at the source code (line 957):
/**
* Return the results of the most recent access point scan, in the form of
* a list of {#link ScanResult} objects.
* #return the list of results
*/
public List<ScanResult> getScanResults(String callingPackage) {
enforceAccessPermission();
int userId = UserHandle.getCallingUserId();
int uid = Binder.getCallingUid();
boolean canReadPeerMacAddresses = checkPeersMacAddress();
boolean isActiveNetworkScorer =
NetworkScorerAppManager.isCallerActiveScorer(mContext, uid);
boolean hasInteractUsersFull = checkInteractAcrossUsersFull();
long ident = Binder.clearCallingIdentity();
try {
if (!canReadPeerMacAddresses && !isActiveNetworkScorer
&& !isLocationEnabled()) {
return new ArrayList<ScanResult>();
}
if (!canReadPeerMacAddresses && !isActiveNetworkScorer
&& !checkCallerCanAccessScanResults(callingPackage, uid)) {
return new ArrayList<ScanResult>();
}
if (mAppOps.noteOp(AppOpsManager.OP_WIFI_SCAN, uid, callingPackage)
!= AppOpsManager.MODE_ALLOWED) {
return new ArrayList<ScanResult>();
}
if (!isCurrentProfile(userId) && !hasInteractUsersFull) {
return new ArrayList<ScanResult>();
}
return mWifiStateMachine.syncGetScanResultsList();
} finally {
Binder.restoreCallingIdentity(ident);
}
}
The first if is checking canReadPeerMacAddresses which the code for checkPeersMacAddress() is:
/**
* Returns true if the caller holds PEERS_MAC_ADDRESS.
*/
private boolean checkPeersMacAddress() {
return mContext.checkCallingOrSelfPermission(
android.Manifest.permission.PEERS_MAC_ADDRESS) == PackageManager.PERMISSION_GRANTED;
}
If you add the permission you can bypass if (!canReadPeerMacAddresses && !isActiveNetworkScorer && !isLocationEnabled()) {. I've tested but I cannot get WIFI MAC list by just using the permission and disabling location.
ACCESS_FINE_LOCATION or ACCESS_COARSE_LOCATION is necessary. To get a valid result, you also have to turn on GPS or get a PEERS_MAC_ADDRESS permission like Setting.
I have tried to simplify my code as much as possible, basically hte issue is that the ActivityRecognitionIntentService appears to be called a couple of times, then stalls out. It appears to be related to the requestCode in the PendingIntent, but I am not sure, can someone please advise me as to what is going wrong? Thanks.
Dashboard.java
public class Dashboard extends Activity implements GoogleApiClient.ConnectionCallbacks,GoogleApiClient.OnConnectionFailedListener {
private BroadcastReceiver receiver;
private TextView tvActivity;
private GoogleApiClient mGoogleApiClient;
//String Locationp = "null";
//private LocationRequest mLocationRequest;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dashboard);
tvActivity = (TextView) findViewById(R.id.tvActivity);
int resp =GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if(resp == ConnectionResult.SUCCESS){
// Create a GoogleApiClient instance
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(ActivityRecognition.API)
//.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
mGoogleApiClient.connect();
}
else{
Toast.makeText(this, "Please install Google Play Service.", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onConnected(Bundle arg0) {
Intent i = new Intent(this, ActivityRecognitionIntentService.class);
PendingIntent mActivityRecognitionPendingIntent = PendingIntent.getService(this, 2000, i, PendingIntent.FLAG_UPDATE_CURRENT);
Log.e("MAIN", "Connected to ActRec");
ActivityRecognition.ActivityRecognitionApi.requestActivityUpdates(mGoogleApiClient, 1000, mActivityRecognitionPendingIntent);
}
#Override
public void onConnectionSuspended(int arg0) {
Log.e("MAIN", "Connection suspended to ActRec");
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.e("MAIN", "Not Connected to ActRec");
}
ActivityRecognitionIntentService.java
public class ActivityRecognitionIntentService extends IntentService {
public ActivityRecognitionIntentService() {
super("ActivityRecognitionIntentService");
}
protected void onHandleIntent(Intent intent) {
if (ActivityRecognitionResult.hasResult(intent)) {
ActivityRecognitionResult result = ActivityRecognitionResult.extractResult(intent);
DetectedActivity mostProbAct = result.getMostProbableActivity();
int confidence = mostProbAct.getConfidence();
String mostProbActName = getActivityName(mostProbAct.getType());
Intent i = new Intent("com.xxx.abc.ACTIVITY_RECOGNITION_DATA");
i.putExtra("act", mostProbActName);
i.putExtra("confidence", confidence);
Log.e("ARS", mostProbActName + "," + confidence);
//sendBroadcast(i);
} else
Log.e("ARS", "Intent had no ActivityRecognitionData");
}
private String getActivityName(int activityType) {
switch (activityType) {
case DetectedActivity.IN_VEHICLE:
return "in_vehicle";
case DetectedActivity.ON_BICYCLE:
return "on_bicycle";
case DetectedActivity.ON_FOOT:
return "on_foot";
case DetectedActivity.STILL:
return "still";
case DetectedActivity.UNKNOWN:
return "unknown";
case DetectedActivity.TILTING:
return "tilting";
}
return "unknown";
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tigerblood.com.node" >
<uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<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"/>
<service android:enabled="true" android:name="com.xxx.abc.ActivityRecognitionIntentService"></service>
<activity
android:name="com.tigerblood.node.Dashboard"
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>
I've found an example of how NFC works. But when I'm attaching the NFC card onResume/OnPause calls. Why?
the function: onNewIntent hasn't called.
The code of Activity:
public class AMain extends Activity {
public static final String MIME_TEXT_PLAIN = "text/plain";
public static final String TAG = "NfcDemo";
private TextView mTextView;
private NfcAdapter mNfcAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.amain);
mTextView = (TextView) findViewById(R.id.tv);
mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (mNfcAdapter == null) {
// Stop here, we definitely need NFC
Toast.makeText(this, "This device doesn't support NFC.", Toast.LENGTH_LONG).show();
finish();
return;
}
if (!mNfcAdapter.isEnabled()) {
mTextView.setText("NFC is disabled.");
} else {
mTextView.setText("NFC is enabled.");
}
handleIntent(getIntent());
}
#Override
protected void onResume() {
super.onResume();
/*
* It's important, that the activity is in the foreground (resumed). Otherwise
* an IllegalStateException is thrown.
*/
setupForegroundDispatch(this, mNfcAdapter);
}
#Override
protected void onPause() {
/*
* Call this before onPause, otherwise an IllegalArgumentException is thrown as well.
*/
stopForegroundDispatch(this, mNfcAdapter);
super.onPause();
}
#Override
protected void onNewIntent(Intent intent) {
/*
* This method gets called, when a new Intent gets associated with the current activity instance.
* Instead of creating a new activity, onNewIntent will be called. For more information have a look
* at the documentation.
*
* In our case this method gets called, when the user attaches a Tag to the device.
*/
handleIntent(intent);
}
private void handleIntent(Intent intent) {
String action = intent.getAction();
Log.d(TAG,action);
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
String type = intent.getType();
if (MIME_TEXT_PLAIN.equals(type)) {
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
new NdefReaderTask().execute(tag);
} else {
Log.d(TAG, "Wrong mime type: " + type);
}
} else if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)) {
// In case we would still use the Tech Discovered Intent
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
String[] techList = tag.getTechList();
String searchedTech = Ndef.class.getName();
for (String tech : techList) {
if (searchedTech.equals(tech)) {
new NdefReaderTask().execute(tag);
break;
}
}
}
}
/**
* #param activity The corresponding {#link Activity} requesting the foreground dispatch.
* #param adapter The {#link NfcAdapter} used for the foreground dispatch.
*/
public static void setupForegroundDispatch(final Activity activity, NfcAdapter adapter) {
final Intent intent = new Intent(activity.getApplicationContext(), activity.getClass());
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
final PendingIntent pendingIntent = PendingIntent.getActivity(activity.getApplicationContext(), 0, intent, 0);
IntentFilter[] filters = new IntentFilter[1];
String[][] techList = new String[][]{};
// Notice that this is the same filter as in our manifest.
filters[0] = new IntentFilter();
filters[0].addAction(NfcAdapter.ACTION_NDEF_DISCOVERED);
filters[0].addCategory(Intent.CATEGORY_DEFAULT);
try {
filters[0].addDataType(MIME_TEXT_PLAIN);
} catch (MalformedMimeTypeException e) {
throw new RuntimeException("Check your mime type.");
}
adapter.enableForegroundDispatch(activity, pendingIntent, filters, techList);
}
/**
* #param activity The corresponding {#link BaseActivity} requesting to stop the foreground dispatch.
* #param adapter The {#link NfcAdapter} used for the foreground dispatch.
*/
public static void stopForegroundDispatch(final Activity activity, NfcAdapter adapter) {
adapter.disableForegroundDispatch(activity);
}
/**
* Background task for reading the data. Do not block the UI thread while reading.
*
* #author Ralf Wondratschek
*
*/
private class NdefReaderTask extends AsyncTask<Tag, Void, String> {
#Override
protected String doInBackground(Tag... params) {
Tag tag = params[0];
Ndef ndef = Ndef.get(tag);
if (ndef == null) {
// NDEF is not supported by this Tag.
return null;
}
NdefMessage ndefMessage = ndef.getCachedNdefMessage();
NdefRecord[] records = ndefMessage.getRecords();
for (NdefRecord ndefRecord : records) {
if (ndefRecord.getTnf() == NdefRecord.TNF_WELL_KNOWN && Arrays.equals(ndefRecord.getType(), NdefRecord.RTD_TEXT)) {
try {
return readText(ndefRecord);
} catch (UnsupportedEncodingException e) {
Log.e(TAG, "Unsupported Encoding", e);
}
}
}
return null;
}
private String readText(NdefRecord record) throws UnsupportedEncodingException {
/*
* See NFC forum specification for "Text Record Type Definition" at 3.2.1
*
* http://www.nfc-forum.org/specs/
*
* bit_7 defines encoding
* bit_6 reserved for future use, must be 0
* bit_5..0 length of IANA language code
*/
byte[] payload = record.getPayload();
// Get the Text Encoding
String textEncoding = ((payload[0] & 128) == 0) ? "UTF-8" : "UTF-16";
// Get the Language Code
int languageCodeLength = payload[0] & 0063;
// String languageCode = new String(payload, 1, languageCodeLength, "US-ASCII");
// e.g. "en"
// Get the Text
return new String(payload, languageCodeLength + 1, payload.length - languageCodeLength - 1, textEncoding);
}
#Override
protected void onPostExecute(String result) {
if (result != null) {
mTextView.setText("Read content: " + result);
}
}
}
}
Manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.nfc"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.NFC" />
<uses-feature
android:name="android.hardware.nfc"
android:required="true" />
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="19" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.nfc.AMain"
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.NDEF_DISCOVERED"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="text/plain" />
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.TAG_DISCOVERED"/>
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.TECH_DISCOVERED"/>
</intent-filter>
<meta-data android:name="android.nfc.action.TECH_DISCOVERED"
android:resource="#xml/nfc_tech_filter" />
</activity>
</application>
</manifest>
You should add NfcAdapter.ACTION_TAG_DISCOVERED to your intent filter. Your current intent filter( filters[0].addAction(NfcAdapter.ACTION_NDEF_DISCOVERED);) only catches NFC tag containin NDEF messages.
by changing your filter to
filters[0].addAction(NfcAdapter.ACTION_TAG_DISCOVERED);
you should get what you want.
Hi have you set the <uses-permission android:name="android.permission.NFC" /> in your ,manifest?