I've began working on a simple Android project recently, but it looks like I just cannot get it to work. I have a main Activity (It has #style/Invisible parameter) which checks if my service is running and starts it if it's not. Also, before the check takes place it starts another activity for result. The activity is expected to return the user's username and password to allow the app to login to the system. The problem is that when I install the app on my phone it works fine, but next time I open the app nothing happens. I have to reinstall it.
Here's the main Activity:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
Intent intent = new Intent(this, LoginGrabber.class);
startActivityForResult(intent, 100);
if(isMyServiceRunning()==false)
{
startService(new Intent(getApplicationContext(), MyService.class));
Log.i("com.connect","startService");
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
if(requestCode == 100){
if(resultCode == RESULT_OK){
String username = data.getStringExtra("Username");
String password = data.getStringExtra("Password");
//TODO Send to server
Toast.makeText(this, "Username: " + username + " Password: " + password, Toast.LENGTH_LONG);
}
}
}
private boolean isMyServiceRunning() {
ActivityManager manager = (ActivityManager) getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (MyService.class.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
LoginGrabber Activity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login_grabber);
}
public void onSendData(View view){
Intent intent = new Intent();
intent.putExtra("Username", ((TextView) findViewById(R.id.email)).getText());
intent.putExtra("Password", ((TextView) findViewById(R.id.password)).getText());
setResult(RESULT_OK, intent);
finish();
}
Here's the Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.app.test"
android:versionCode="2"
android:versionName="2.0">
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="18" />
<supports-screens
android:largeScreens="true"
android:resizeable="true"
android:xlargeScreens="true" />
<uses-permission
android:name="android.permission.INTERNET"
android:required="true" />
<application
android:icon="#drawable/launcher"
android:label="#string/app_name"
android:theme="#style/Invisible">
<activity
android:name="com.connect.Main"
android:excludeFromRecents="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
<service
android:name="com.connect.MyService"
android:enabled="true"
android:exported="true" />
<activity
android:theme="#style/AppTheme"
android:name="com.connect.LoginGrabber"
android:label="#string/title_activity_login_grabber" />
</application>
</manifest>
What am I doing wrong?
Thanks for your help!
OK! I found the problem! The problem was that my application was crashing as soon as the service was started because I was testing the app without internet and without handling errors that were thrown when there was no internet available.
Just had to turn WiFi on, that's it!
Related
With my basic knowledge on Android, I'm trying to play with the Google voice APIs and followed the example here and to write an app, which would allow me to call a hardcoded number. Unfortunately i'm getting an error saying < identifier > expected, so i'm unable to check if my app even works. Can someone see what is missing here and also if i'm even going in the right direction with my thinking and code.
Java file:
public class MyVoiceActivity extends Activity {
class Confirm extends VoiceInteractor.ConfirmationRequest {
public Confirm(String ttsPrompt, String visualPrompt) {
VoiceInteractor.Prompt prompt = new VoiceInteractor.Prompt(
new String[] {ttsPrompt}, visualPrompt);
super(prompt, null);
}
#Override public void onConfirmationResult(boolean confirmed, Bundle null) {
if (confirmed) {
call();
}
finish();
}
};
#Override public void onResume() {
if (isVoiceInteractionRoot()) {
call();
}
Intent intent = new Intent(this, MyVoiceActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish();
}
private void call () {
try {
final Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setData(Uri.parse("tel:12345678"));
startActivity(callIntent);
} catch (ActivityNotFoundException activityException) {
}
}
}
AndroidManifest file:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ccvoice.bt.examplevoice">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity
android:name=".MyVoiceActivity" >
<intent-filter>
<action android:name="android.intent.action.CALL" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.VOICE" />
</intent-filter>
</activity>
</application>
</manifest>
The < identifier > required error i'm getting is in this line of the code:
public void onConfirmationResult(boolean confirmed, Bundle null) {
Thank you in advance.
null is a reserved word and cannot be used as an identifier (eg. the name of a parameter). Use a different name for your Bundle parameter to that method.
public void onConfirmationResult(boolean confirmed, Bundle bundle) {
I'm trying to implement complication support for my watch. Here's my AndroidManifest.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.wearapp">
<uses-feature android:name="android.hardware.type.watch"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="com.google.android.wearable.permission.RECEIVE_COMPLICATION_DATA"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#android:style/Theme.DeviceDefault">
<!-- Watch Face -->
<service
android:name=".ComplicationSimpleWatchFaceService"
android:enabled="true"
android:label="Fancy Watch"
android:permission="android.permission.BIND_WALLPAPER">
<meta-data
android:name="android.service.wallpaper"
android:resource="#xml/watch_face"/>
<meta-data
android:name="com.google.android.wearable.watchface.preview"
android:resource="#drawable/preview_complication_simple"/>
<meta-data
android:name="com.google.android.wearable.watchface.preview_circular"
android:resource="#drawable/preview_complication_simple"/>
<meta-data
android:name="com.google.android.wearable.watchface.wearableConfigurationAction"
android:value="com.example.wearapp.CONFIG_COMPLICATION_SIMPLE"/>
<intent-filter>
<action android:name="android.service.wallpaper.WallpaperService"/>
<category android:name="com.google.android.wearable.watchface.category.WATCH_FACE"/>
</intent-filter>
</service>
<activity android:name="android.support.wearable.complications.ComplicationHelperActivity"/>
<activity
android:name=".ComplicationSimpleConfigActivity"
android:label="Fancy Watch">
<intent-filter>
<action android:name="com.example.wearapp.CONFIG_COMPLICATION_SIMPLE"/>
<category android:name="com.google.android.wearable.watchface.category.WEARABLE_CONFIGURATION"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
</application>
</manifest>
I have a watch face service and a config activity. When I use ComplicationHelperActivity to createProviderChooserHelperIntent from the config activity I always get result cancelled in the onActivityResult. Here's how I start chooser activity and listen for the result
#Override
public void onClick(WearableListView.ViewHolder viewHolder) {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "onClick()");
}
Integer tag = (Integer) viewHolder.itemView.getTag();
ComplicationItem complicationItem = mAdapter.getItem(tag);
startActivityForResult(ComplicationHelperActivity.createProviderChooserHelperIntent(
getApplicationContext(),
complicationItem.watchFace,
complicationItem.complicationId,
complicationItem.supportedTypes),
PROVIDER_CHOOSER_REQUEST_CODE);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == PROVIDER_CHOOSER_REQUEST_CODE
&& resultCode == RESULT_OK) {
ComplicationProviderInfo complicationProviderInfo =
data.getParcelableExtra(ProviderChooserIntent.EXTRA_PROVIDER_INFO);
Log.d(TAG, "Selected Provider: " + complicationProviderInfo);
finish();
}
}
It seems like I'm missing complication support and that's why can't choose any provider. But to test this I copied ComplicationSimpleWatchFaceService from the WatchFace sample and still don't have any result. Here's complication code from the watch face.
private static final int LEFT_DIAL_COMPLICATION = 0;
private static final int RIGHT_DIAL_COMPLICATION = 1;
public static final int[] COMPLICATION_IDS = {LEFT_DIAL_COMPLICATION, RIGHT_DIAL_COMPLICATION};
public static final int[][] COMPLICATION_SUPPORTED_TYPES = {
{ComplicationData.TYPE_SHORT_TEXT},
{ComplicationData.TYPE_SHORT_TEXT}
};
private void initializeComplication() {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "initializeComplications()");
}
mActiveComplicationDataSparseArray = new SparseArray<>(COMPLICATION_IDS.length);
mComplicationPaint = new Paint();
mComplicationPaint.setColor(Color.WHITE);
mComplicationPaint.setTextSize(COMPLICATION_TEXT_SIZE);
mComplicationPaint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD));
mComplicationPaint.setAntiAlias(true);
setActiveComplications(COMPLICATION_IDS);
}
Make sure that you have called the ComplicationHelperActivity.createProviderChooserHelperIntent method, to obtain an intent and to start the provider chooser.
Sample code (make sure to call the getActivity() method for it to launch):
startActivityForResult(
ComplicationHelperActivity.createProviderChooserHelperIntent(
getActivity(),
watchFace,
complicationId,
ComplicationData.TYPE_LARGE_IMAGE),
PROVIDER_CHOOSER_REQUEST_CODE);
The intent can be used with either startActivity or startActivityForResult to launch the chooser.
You can followed this tutorial and see if you missed some configurations.
It's a specific question and I've done a bit of Android development before, but not so deep into the system management.
So I need to create an app which run in background (this part is OK) and to launch automatically an activity of the app when a special shortcut (let's say #123*6) is typed from the phone app software keyboard on the phone.
Can you please indicate me if it's possible, and if yes, what API/Component I should use? Can't find something relevant on the Web.
Ok I finally got this working on the HTC device. The fact is Samsung phones doesn't seems to react to secret codes ...
I simply have this manifest :
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MenuBrowser"
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=".ShortcodeService"
android:exported="false">
</service>
<receiver
android:name=".ShortcodeReceiver"
android:enabled="true">
<intent-filter>
<action android:name="android.provider.Telephony.SECRET_CODE" />
<data android:scheme="android_secret_code" android:host="1992" />
</intent-filter>
</receiver>
</application>
My service is simply checking for the right permissions for Android M (6.0), because the security has changed a bit. We now have to declare permission on-the-fly during the application runtime, and not at installation.
My activity:
public class MenuBrowser extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d("USSDBrowser", "Start app");
//if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_PHONE_STATE, Manifest.permission.PROCESS_OUTGOING_CALLS}, 10);
Intent serviceIntent = new Intent(this.getApplicationContext(), ShortcodeService.class);
startService(serviceIntent);
//setContentView(R.layout.activity_menu_browser);
finish();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_menu_browser, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
And my receiver is like this :
public class ShortcodeReceiver extends BroadcastReceiver {
private static String defaultCode = "1992";
#Override
public void onReceive(Context context, Intent intent) {
Log.d("USSDBrowser", "Intent received");
if(intent.getAction().equals("android.provider.Telephony.SECRET_CODE")) {
String code = intent.getDataString();
if(code.equals("android_secret_code://" + defaultCode)) {
Log.d("USSDBrowser", "Code received !!! ");
}
//Intent in = new Intent(context, MenuBrowser.class);
//context.startActivity(in);
Toast.makeText(context, "You typed a shortcode, hype !", Toast.LENGTH_LONG).show();
}
}
}
But now I tested that and it's working for HTC One S (Android 4.1.1) and Aquaris E4 (Android 4.4.2).
The phones tested that does not capture secret code intents are : Samsung Galaxy S4 and Galaxy S6 (Android 6.0).
I've the same issue described here but i can't understand whats wrong.
My issue is: Unable to start service Intent { act=.connections.MoodyService } U=0: not found
EDIT
I've changed my package from connections to service in the source code, sorry for the confusion
My manifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.moody"
android:installLocation="auto"
android:versionCode="0"
android:versionName="0.6.7 alpha" >
<uses-sdk
android:maxSdkVersion="18"
android:minSdkVersion="14"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:allowClearUserData="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="activities.MainActivity"
android:label="#string/app_name" >
</activity>
<activity
android:name="activities.Menu_esq"
android:label="#string/title_activity_menu_esq" >
</activity>
<activity
android:name="activities.BaseActivity"
android:label="#string/title_activity_base" >
</activity>
<activity
android:name="activities.MainView"
android:label="#string/title_activity_main_view" >
</activity>
<activity
android:name="activities.LoginActivity"
android:label="#string/app_name"
android:noHistory="true"
android:windowSoftInputMode="adjustResize|stateVisible" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.example.moody.LeftActivity"
android:label="#string/title_activity_left" >
</activity>
<activity
android:name="com.example.moody.RightActivity"
android:label="#string/title_activity_right" >
</activity>
<activity
android:name="activities.UserDetailsActivity"
android:label="#string/title_activity_user_details" >
</activity>
<activity
android:name="fragments.TopicsPreview"
android:label="#string/title_activity_copy_of_topics_preview" >
</activity>
<activity android:name="activities.Loading" >
</activity>
<service
android:name=".service.MoodyService"
android:icon="#drawable/ic_launcher"
android:label="#string/moody_service" >
</service>
</application>
service is the package and MoodyService is the class name
My service class
public class MoodyService extends Service {
public MoodyService() {
// TODO Auto-generated constructor stub
}
private boolean isRunning = false;
Object getContent;
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
// Announcement about starting
Toast.makeText(this, "Starting the Demo Service", Toast.LENGTH_SHORT)
.show();
// Start a Background thread
isRunning = true;
Thread backgroundThread = new Thread(new BackgroundThread());
backgroundThread.start();
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
// Stop the Background thread
isRunning = false;
// Announcement about stopping
Toast.makeText(this, "Stopping the Demo Service", Toast.LENGTH_SHORT)
.show();
}
private class BackgroundThread implements Runnable {
int counter = 0;
public void run() {
try {
counter = 0;
while (isRunning) {
System.out.println("" + counter++);
new Contents().getAll(getResources(),
getApplicationContext());
Thread.currentThread().sleep(5000);
}
System.out.println("Background Thread is finished.........");
} catch (Exception e) {
e.printStackTrace();
}
}
}
And in my main Intent.
Intent start = new Intent(".service.MoodyService");
this.startService(start);
and also tried
Intent intent = new Intent(this, MoodyService.class);
this.startService(intent);
and tried with the full path
<service
android:name="com.example.moody.service.MoodyService"
android:icon="#drawable/ic_launcher"
android:label="#string/moody_service" >
Solved
I deleted the period in the beginning of the package name in the manifest and it worked, in another words:
This doesn't work:
.yourPackage.YourClass
But this does work:
yourPackage.YourClass
And in the main:
Intent intent = new Intent(this, MoodyService.class);
this.startService(intent);
But it goes against what is written in the documentation:
android:name The name of the Service subclass that implements the service. This should be a fully qualified class name (such as,
"com.example.project.RoomService"). However, as a shorthand, if the
first character of the name is a period (for example, ".RoomService"),
it is appended to the package name specified in the
element. Once you publish your application, you should not change this
name (unless you've set android:exported="false").
There is no default. The name must be specified.
The service must be also be included in the Manifest:
<service android:name="com.x.x.serviceclass"></service>
Make sure you have declared your service in the manifest file.
<service
android:name=".MyService"
android:enabled="true" >
</service>
and try writing getApplicationContext() instead of "this" keyword
startService(new Intent(getApplicationContext(), MoodyService.class));
I don't know why you are using that package-like name for your service name, but why don't you use class name for starting the service?
Intent intent = new Intent(context, YourService.class);
context.startService(intent);
I think in manifest package name for service is wrong as you said your package name is connections so it should be like this
android:name ="connections.MoodyService"
or
android:name="com.example.moody.connections.MoodyService"
to invoke service do
Intent intent = new Intent(this, MoodyService.class);
this.startService(intent);
my service is in "service" package and my manifest service enrty like this;
<service
android:name="service.TimerService"
android:exported="false" >
</service>
Did you create an empty constructor in the service?
If not, try that.
Also uncertain if you can use the Intent like that. You could try the 'new Inten(this, MoodyService.class)' construction.
Did you try to use the android:name that you specified in the Manifest?
Android Manifest:
<service
android:enabled="true"
android:name="UploadService" />
The call would be sth like this:
Intent intent = new Intent("UploadService");
I was following the example code for the Device Admin app. My attempts to start activity that enables the user to add a device admin app has failed. The following is the code which I use to try and start this.
public class DeviceAdminTestActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ComponentName deviceAdminReceiver = new ComponentName(this, TestAdminReceiver.class);
Intent i = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
i.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, deviceAdminReceiver);
i.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "My Explanantion");
// startActivityForResult(i, 1);
try{
startActivity(i);
}catch(Exception ex){
Toast.makeText(this, ex.getMessage(), Toast.LENGTH_LONG);
}
}
}
The following is the code of the Receiver...
public class TestAdminReceiver extends DeviceAdminReceiver {
#Override
public void onEnabled(Context context, Intent intent) {
Toast.makeText(context, "On Enabled", Toast.LENGTH_SHORT).show();
}
#Override
public CharSequence onDisableRequested(Context context, Intent intent) {
return ("You are about to disable device admin");
}
#Override
public void onDisabled(Context context, Intent intent) {
Toast.makeText(context, "On Disabled", Toast.LENGTH_SHORT).show();
}
#Override
public void onPasswordChanged(Context context, Intent intent) {
Toast.makeText(context, "On Password Changed", Toast.LENGTH_SHORT).show();
}
}
And finally, here is the manifest...
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.zeezulander.admintest"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="8" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:name="org.zeezulander.admintest.DeviceAdminTestActivity"
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=".TestAdminReceiver" android:permission="android.permission.BIND_DEVICE_ADMIN" android:label="Test Admin">
<meta-data android:resource="#xml/admin_data" android:name="adminMetaData"/>
<intent-filter >
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED"/>
</intent-filter>
</receiver>
</application>
I do not get an error even. My Activity starts, but nothing happens beyond, no error even.
Maybe something is wrong with the layout. If you're not getting an error, then it isn't crashing, and if it isn't crashing then the only thing that could be wrong is the display (layout).
final Intent intent = new Intent();
intent.setComponent(new ComponentName("com.android.settings", "com.android.settings.DeviceAdminAdd"));
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, adminReceiver);
intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "To use all features activate it.");
overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left);
startActivityForResult(intent, ACTIVATION_REQUEST);