Skip to content →

diego.org Posts

Errors while installing APK from Android shell

I ran into 2 error while trying to install an APK from the Android shell. Note the apk is on the Android filesystem and I am installing it from the shell, not using adb.

The first error I got was: INSTALL_FAILED_INVALID_URI

$ pm install myApp.apk
pkg: myApp.apk
Failure [INSTALL_FAILED_INVALID_URI]

This is because you need to give the full path to the apk, like:

$ pm install /sdcard/myApp.apk

The next error I got was INSTALL_FAILED_UID_CHANGED:

$ pm install /sdcard/myApp.apk
pkg: /sdcard/myApp.apk
Failure [INSTALL_FAILED_UID_CHANGED]

I was installing over an existing app. The first thing I tried was to uninstall the app, but that didn’t work. I found that removing the data directory for the app solved my problem:

$ rm -rf /data/data/com.my.app.myApp/
Comments closed

Cocoapods – Generated duplicate UUIDs

I recently added another target to my Podfile to support tvOS. Here is an example of what the Podfile looks like:

source ‘https://github.com/CocoaPods/Specs.git’
use_frameworks!

target ‘AppiOS’ do
platform :ios, ‘9.0’
pod ‘AFNetworking’, ‘3.0.0-beta.1’
end

target ‘AppTV’ do
platform :tvos, ‘9.0’
pod ‘AFNetworking’, ‘3.0.0-beta.1’
end

I got this really long error complaining of duplicate UUIDS. Here is a shortened version:

[!] [Xcodeproj] Generated duplicate UUIDs:

PBXFileReference —
…. /Products/AFNetworking.framework

From what I understand, this deterministic UUIDs is a harmless warning and can be disabled by running the following command in the terminal. Then run pod install again.

$ export COCOAPODS_DISABLE_DETERMINISTIC_UUIDS=YES
Comments closed

Downgrading Cocoapods

I recently had some issues with a pre-release version of Cocoapods. To fix it, the suggestion was to downgrade Cocoapods to a previous version. It wasn’t obvious how to do that, but this is what I learned.

First you can figure out which version of Cocoapods you are on with the command:

pod –version

You can also see all the version of Cocoapods you have installed with this command:

sudo gem list cocoapods

Next uninstall Cocoapods. If you have multiple version, you will have the choice of uninstalling all or a specific version.

sudo gem uninstall cocoapods

Finally you can install the specific version with this command:

sudo gem install cocoapods -v 0.39.0.beta.3
Comments closed

Apple Watch Workout App

I’ve been using the Apple Watch Workout App since the end of April. While I really like it, it has a few things which could be better. Here are my thoughts on the Apple Watch 1.0 Workout App.

When you start a workout, you get to choose what type of workout you are doing. For my case I primarily do an Outdoor Run or Outdoor Cycle.

IMG_5432

Then you can choose between an Open Goal, a Distance Goal or a Calorie Goal. Fo my case, I always do an Open Goal.
IMG_5433

You hit the start button and it counts down from 3. I’m not sure why it needs to do this. When I start, I want to start, I don’t want to wait 3 seconds.

Then you are shown a pageable screen. You can page between: Elapsed Time, Speed/Pace, Distance, Calories, and Heart Rate.

IMG_5316 IMG_5317 IMG_4974 IMG_4973

 

Apple got one thing right here.  They always show the time.  I’ve used Run Keeper on the Pebble and it drove me crazy that the time was not visible.  This is a watch, the time should always be visible.

The workout app is almost like a watch face in that it stays the current app while you are working out.  This is nice because it would be a pain to keep on reloading the Workout app.

Consolidated Metrics View

The first thing I’d like to see is a page that has all of these metrics on it. Why should I have to page through all the metrics separately when I could view them at one time.  The text would need to be smaller, but it could all fit.  One problem I have is when working out and my hands get sweaty, it’s impossible to register swipes and taps on the watch.  Sometimes I need to stop and dry my hands off so I can switch between pages.  I would be nice to see them all at one glance.

Notifications

Often while I’m working out, a notification will come in.  And for whatever reason, I don’t have time to check it at that second.  If I don’t check quick enough, it disappears.  To view it, I have to go back to the watch face and swipe down.  This is a lot of steps. Why can’t the workout app be like the watch face.  Put a red dot at the top when their are unread notifications and allow me to swipe down to view them.

Glances

For the same reason, why not give me glances too.  I often want to swipe up to use glances to change a song or some other action.

Loosing Contact

This really annoys me.  I often glance down at my watch and see it back on the watch face with the screen locked.  I probably hit a bump on my bike and it lost contact from my skin long enough to lock.  When this happen, sometimes is continues to track my workout.  Most times it pauses my workout.  Then when you unlock the phone, it loads the workout app and and the spinner just spins.  You have to exit the app and reopen the app.  Try doing this on your bike.  It’s impossible.  I have to stop and make my watch happy again.  The watch should be smart enough.  If I’m in the middle of a workout, please be more forgiving about losing contact with my skin.   I’d even be happy with a preference that I have to accept to make my watch less secure to make this happen.  Or at least notify me when I’ve lost contact and it’s locked.  It’s frustrating to be doing a workout and loose a couple of miles to this.

Sweat

As I mentioned before, the watch is almost impossible to use with sweaty hands.  I’m not sure what can be done about this from a software perspective, except to give me more things that require me to touch my watch less.

Pause While Driving

One thing that Apple got right, is that is pauses the app if you are doing a workout and drive in the car. I’ve done this many times.  I’m out for a run somewhere I had to drive to.  When I finish I get back in the car and drive home.  When using Runkeeper, this would result in extra mileage on my run.  The Apple Watch app stops recording.  This is brilliant.

I’m hoping that Apple Watch 2.0 Software or the next hardware version will fix some of these issues.

Comments closed

Mac Lock

icon-512@xOne of my favorite features of Alfred 2 for Mac is typing “Lock” to lock the screen. When I switched back to using Spotlight, I missed this feature. I created a Mac app that would lock the screen when launched. You can now type “Lock” in Spotlight to lock the screen or put it in the Dock and lock the screen with one click.

Source: https://github.com/dougdiego/mac-lock

Download: Lock.dmg

Comments closed

WWDC 2015 – Wish list

Last year I made a WWDC 2014 Wish List. I got at least one thing I wanted. But Apple also gave me a whole bunch of things that I didn’t know I wanted.

Here is an updated list for WWDC 2015.

  • Bug Fixes – I’d be very happy if there were less new features and more bug fixes with the current products.  For example please fix the networking issues.  And I’m still having issues with Gmail in OS X Mail.
  • 3rd Party Complications on Apple Watch – Complications are awesome.  I’d like to be able to expose a complication from my app.
  • Complications on iOS Home Screen – Having complications on the Apple Watch, makes me want them on the iOS home screen.
  • Siri Extensibility – I’d like to see Apple open up Siri to third party apps.  For example if I have RunKeeper on my iPhone, I’d like to be able to tell Siri “Start my run”, “End my run”.  When Apple announced HomeKit in 2014, it allowed custom names for things in your house.  A step forward, but I’d like to see more.
  • AppleTV SDK – I’d love to be able to write apps for the AppleTV.
  • Sandboxing – I’m glad that Apple has sandboxing in the Mac App Store.  But it’s too restrictive.  Apps like Coda should be able to run.  Apple should start by sandboxing Xcode.
  • Filesystem – Mac OS X and iOS are due for a new filesystem. ZFS was rumored for awhile but fell through.
  • Extensions – I love extensions, but there are a few problems.  The difference between a share and action extension is confusing.  It’s hard to tell when new extension are available.   There should be more trigger points for extensions.
  • Default Applications on iOS – On OS X you can set a default application for things like mail and web browser.  I wish you could do the same on iOS.
  • Multiple profiles on iOS – It would be nice if iOS supported multiple users, so a family could share an iPad.
Comments closed

Android Sort ScanResult by Signal Strength


// Get List of ScanResults
List<ScanResult> wifiList = wifiManager.getScanResults();

// Create Temporary HashMap
HashMap<String, ScanResult> map = 
  new HashMap<String, ScanResult>();

// Add ScanResults to Map to remove duplicates
for (ScanResult scanResult : wifiList) {
  if (scanResult.SSID != null && 
     !scanResult.SSID.isEmpty()) {
    map.put(scanResult.SSID, scanResult);
  }
}

// Add to new List
List<ScanResult> sortedWifiList = 
  new ArrayList<ScanResult>(map.values());

// Create Comparator to sort by level
Comparator<ScanResult> comparator = 
  new Comparator<ScanResult>() {

  @Override
  public int compare(ScanResult lhs, ScanResult rhs) {
    return (lhs.level < rhs.level ? -1 : (lhs.level == rhs.level ? 0 : 1));
  }
};

// Apply Comparator and sort
Collections.sort(sortedWifiList, comparator);            
Comments closed

Remove Divider in an Android ListView

I’ve had to remove the divider in an Android ListView several times now, so here’s a quick reminder of myself.

This can be done in XML or in Java by setting the dividerHeight to 0 and the divider to null:

XML


<ListView
android:id="@+id/listView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:dividerHeight="0dp"
android:divider="@null"/>

Java


ListView listView = 
(ListView)findViewById(R.id.listView);
listView.setDividerHeight(0);
listView.setDivider(null);
Comments closed

Embedding Crosswalk in Android Studio

An updated version of this post can be found at: https://diego.org/2016/09/20/embedding-crosswalk-in-android-studio-updated/

Note: The Crosswalk team has stopped development on this project. You can read more about it here: Crosswalk 23 to be the last Crosswalk release

Crosswalk is a web runtime that replaces the built in WebView used by Android. Crosswalk is based on Google Chromium. Why use Crosswalk and not the built in WebView? The built in WebView varies greatly with each Android OS version. I’ve run into many problems because of the differences between the two. When you use Crosswalk you can work with a consistent WebView across all Android OS versions. Besides that, it has better HTML5 support. Read this article for more reasons “Why use Crosswalk for Android Builds?

The instructions for embedding Crosswalk in your application are based on ADT and they are complicated. Adding Crosswalk to Android Studio is much easier if you use the maven2 releases.

Here are steps for creating a new Android application in Android Studio and embedding Crosswalk.

Create a new Android Project

From the menu choose “File > New Project”

Give your application a name “CrosswalkDemo”

Give it a domain and project location and press “Next”.

Select “Phone and Tablet”, Minimum SDK “API 19” and press “Next”.

Select “Blank Activity” and press “Next”.

Use the defaults for the Activity name and press “Finish”.

Configure Crosswalk

Identify which Crosswalk release you want to install. You can find the releases here:
https://download.01.org/crosswalk/releases/crosswalk/android/maven2/

For this demo I choose version 10.39.235.15, which is found here:
https://download.01.org/crosswalk/releases/crosswalk/android/maven2/org/xwalk/xwalk_core_library/10.39.235.15/

Open the file:
CrosswalkDemo/app/build.gradle

First we need to add the Maven repository like this:


repositories {
    maven {
        url 'https://download.01.org/crosswalk/releases/crosswalk/android/maven2'
    }
}

Then add this to your dependencies:


compile 'org.xwalk:xwalk_core_library:10.39.235.15'

The finished file should look like:


apply plugin: 'com.android.application'

android {
    compileSdkVersion 21
    buildToolsVersion "20.0.0"

    defaultConfig {
        applicationId "org.diego.android.crosswalkdemo"
        minSdkVersion 19
        targetSdkVersion 21
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

repositories {
    maven {
        url 'https://download.01.org/crosswalk/releases/crosswalk/android/maven2'
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:21.0.0'
    compile 'org.xwalk:xwalk_core_library:10.39.235.15'
}

Update the Code

Add an XWalkView to your layout like:


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#000000">

<org.xwalk.core.XWalkView
android:id="@+id/xwalkWebView"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#000000"
/>

</LinearLayout>

In your activity, find the XWalkView and then load a url like:


xWalkWebView=(XWalkView)findViewById(R.id.xwalkWebView);
xWalkWebView.load("https://crosswalk-project.org", null);

That’s pretty much it.

The entire activity looks like:


package org.diego.android.crosswalkdemo;

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;

import org.xwalk.core.XWalkPreferences;
import org.xwalk.core.XWalkView;


public class MainActivity extends ActionBarActivity {
    private XWalkView xWalkWebView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        xWalkWebView=(XWalkView)findViewById(R.id.xwalkWebView);
        xWalkWebView.load("https://crosswalk-project.org", null);

        // turn on debugging
        XWalkPreferences.setValue(XWalkPreferences.REMOTE_DEBUGGING, true);
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (xWalkWebView != null) {
            xWalkWebView.pauseTimers();
            xWalkWebView.onHide();
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (xWalkWebView != null) {
            xWalkWebView.resumeTimers();
            xWalkWebView.onShow();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (xWalkWebView != null) {
            xWalkWebView.onDestroy();
        }
    }

}

You can download a sample project here:
https://github.com/dougdiego/CrosswalkDemo

More details about the AAR Crosswalk release can be found here:
https://crosswalk-project.org/documentation/embedding_crosswalk/crosswalk_aar.html

Comments closed

iOS File Size Formatter

iOS has a handy formatter for file sizes. Here is an example of formatting at long into a readable string:


// Get file size
unsigned long long size = [[NSFileManager defaultManager]
attributesOfItemAtPath:path error:nil].fileSize;
NSLog(@"size: %@", @(size));

// Format file size to a readable string
NSString * fileSize = [NSByteCountFormatter stringFromByteCount:size
countStyle:NSByteCountFormatterCountStyleFile];
NSLog(@"fileSize: %@", fileSize);

Output:

size: 65346
fileSize: 65 KB

Comments closed