In this post I will cover Android KitKat developmnet including the main items like
– Printing Framework
– SMS Provider
– Animations using Transition Manager
– The New Sensor Manager
Printing Framework
PrintManager pManager = (PrintManager) this.getSystemService(Context.PRINT_SERVICE); String job_name = this.getString(R.string.app_name) + " Document"; pManager.print(job_name, pda, null); PrintDocumentAdapter pda = new PrintDocumentAdapter(){ @Override public void onWrite(PageRange[] pages, ParcelFileDescriptor destination, CancellationSignal cancellationSignal, WriteResultCallback callback){ InputStream input = null; OutputStream output = null; try { input = new FileInputStream(file to print); output = new FileOutputStream(destination.getFileDescriptor()); byte[] buf = new byte[1024]; int bytesRead; while ((bytesRead = input.read(buf)) > 0) { output.write(buf, 0, bytesRead); } callback.onWriteFinished(new PageRange[]{PageRange.ALL_PAGES}); } catch (FileNotFoundException ee){ //Catch exception } catch (Exception e) { //Catch exception } finally { try { input.close(); output.close(); } catch (IOException e) { e.printStackTrace(); } } } @Override public void onLayout(PrintAttributes oldAttributes, PrintAttributes newAttributes, CancellationSignal cancellationSignal, LayoutResultCallback callback, Bundle extras){ if (cancellationSignal.isCanceled()) { callback.onLayoutCancelled(); return; } int pages = computePageCount(newAttributes); PrintDocumentInfo pdi = new PrintDocumentInfo.Builder("Name of file").setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT).build(); callback.onLayoutFinished(pdi, true); } };
You can check what printers are supported HERE on the Google’s page
SMS Provider
The Manifest
<manifest> ... <application> <!-- BroadcastReceiver that listens for incoming SMS messages --> <receiver android:name=".SmsReceiver" android:permission="android.permission.BROADCAST_SMS"> <intent-filter> <action android:name="android.provider.Telephony.SMS_DELIVER" /> </intent-filter> </receiver> <!-- BroadcastReceiver that listens for incoming MMS messages --> <receiver android:name=".MmsReceiver" android:permission="android.permission.BROADCAST_WAP_PUSH"> <intent-filter> <action android:name="android.provider.Telephony.WAP_PUSH_DELIVER" /> <data android:mimeType="application/vnd.wap.mms-message" /> </intent-filter> </receiver> <!-- Activity that allows the user to send new SMS/MMS messages --> <activity android:name=".ComposeSmsActivity" > <intent-filter> <action android:name="android.intent.action.SEND" /> <action android:name="android.intent.action.SENDTO" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="sms" /> <data android:scheme="smsto" /> <data android:scheme="mms" /> <data android:scheme="mmsto" /> </intent-filter> </activity> <!-- Service that delivers messages from the phone "quick response" --> <service android:name=".HeadlessSmsSendService" android:permission="android.permission.SEND_RESPOND_VIA_MESSAGE" android:exported="true" > <intent-filter> <action android:name="android.intent.action.RESPOND_VIA_MESSAGE" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="sms" /> <data android:scheme="smsto" /> <data android:scheme="mms" /> <data android:scheme="mmsto" /> </intent-filter> </service> </application> </manifest>
Activity should behave like below:
public class ComposeSmsActivity extends Activity { @Override protected void onResume() { super.onResume(); final String myPackageName = getPackageName(); if (!Telephony.Sms.getDefaultSmsPackage(this).equals(myPackageName)) { View viewGroup = findViewById(R.id.not_default_app); viewGroup.setVisibility(View.VISIBLE); Button button = (Button) findViewById(R.id.change_default_app); button.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { Intent intent = new Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT); intent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME, myPackageName); startActivity(intent); } }); } else { View viewGroup = findViewById(R.id.not_default_app); viewGroup.setVisibility(View.GONE); } } }
String defaultSmsApp = Telephony.Sms.getDefaultSmsPackage(context); Intent intent = new Intent(context, Sms.Intents.ACTION_CHANGE_DEFAULT); intent.putExtra(Sms.Intents.EXTRA_PACKAGE_NAME, context.getPackageName()); startActivity(intent); Intent intent = new Intent(context, Sms.Intents.ACTION_CHANGE_DEFAULT); intent.putExtra(Sms.Intents.EXTRA_PACKAGE_NAME, defaultSmsApp); startActivity(intent);
Animations using Transition Manager
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_transition_scene_1, container, false); final Scene scene = Scene.getSceneForLayout(container, R.layout.fragment_transition_scene_2, getActivity()); Button goButton = (Button)rootView.findViewById(R.id.goButton); goButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { TransitionManager.go(scene); } }); return rootView; }
The New Sensor Manager
private SensorManager sensorManager; private TextView count; boolean activityRunning; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); count = (TextView) findViewById(R.id.count); sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); } @Override protected void onResume() { super.onResume(); activityRunning = true; Sensor countSensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER); if (countSensor != null) { sensorManager.registerListener(this, countSensor, SensorManager.SENSOR_DELAY_UI); } else { Toast.makeText(this, "Count sensor not available!", Toast.LENGTH_LONG).show(); } } @Override protected void onPause() { super.onPause(); activityRunning = false; // if you unregister the last listener, the hardware will stop detecting step events // sensorManager.unregisterListener(this); } @Override public void onSensorChanged(SensorEvent event) { if (activityRunning) { count.setText(String.valueOf(event.values[0])); } } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { }
Device Features
The following are new device features introduced in KitKat that can be declared with the <uses-feature> tag. These features declare your app requirements and enable filtering on Google Play or check for at runtime:
FEATURE_CONSUMER_IR
FEATURE_DEVICE_ADMIN
FEATURE_NFC_HOST_CARD_EMULATION
FEATURE_SENSOR_STEP_COUNTER
FEATURE_SENSOR_STEP_DETECTOR
App Permissions
The following are new permissions can be added in the manifest which your app must request with the <uses-permission> tag to use certain new APIs:
INSTALL_SHORTCUT
UNINSTALL_SHORTCUT
TRANSMIT_IR
Top 10 Android App Development Trends | 2020 Guide
Animations In Android KitKat
Step Counter App With Android KitKat 4.4
Get Phone Type GSM/CDMA In Android Development
Sort The File In File Explorer By Implementing Comparator in Android Development
How To Get FileExplorer History In Android Development
Get File Extension And MIME Type In Android Development
Custom Dialog with EditText in Android Development